안드로이드는 리눅스 커널 기반으로 구글에서 제작하고 있는 오픈소스 모바일 운영체제이다. 그리고 구글은 안드로이드의 소스코드를 공개하고 있다.(칩셋 업체의 Board Support Pachage 부분은 미공개) 개방성과 범용성이 뛰어나 여러 플랫폼으로 이식 및 개발이 가능하다.
가장 큰 차이점은 GAPPS의 유무이다.
AOSP를 구현하는 기기는 두가지 호환성 수준, AOSP 호환성과 안드로이드 호환성이 있다.
AOSP 호환 기기는 호환성 정의 문서(CDD)의 요구 사항 목록을 준수해야한다. 안드로이드 호환 기기는 CDD
및 공급업체 소프웨어 요구사항(VSR)의 요구사항 목록을 준수하고 공급업체 테스트 모음(VTS) 및 호환성 테스트 모음과 같은 테스트를 실행해야한다.
자세한 내용은 안드로이드 호환성 프로그램을 참고한다.
AOSP용 소프트웨어 스택에는 다음과 같은 레이어가 포함됩니다.

안드로이드 API만 사용하여 만든 앱이다.
안드로이드와 시스템 API를 조합하여 만든 앱이다. 이 앱은 기기에 권한이 있는 앱으로 사전 설치되어 있어야 한다.
안드로이드 API, 시스템 API, 안드로이드 프레임워크 구현에 관한 직접 액세스를 조합하여 만든 앱이다. 기기 제조 업체가 안드로이드 프레임워크 내에서 불안정한 API에 직접 액세스할 수도 있으므로 이러한 앱은 기기 에 사전 설치되어 있어야 하고 기기의 시스템 소프트웨어가 업데이트 될 때만 업데이트를 할 수 있다.
시스템 API는 파트너 및 OEM이 번들 애플리케이션에 포함하기 위해서만 사용할 수 있는 안드로이드 API를 나타낸다. 이러한 API는 소스코드에서 @SystemApi로 표시한다.
안드로이드 API는 서드 파티 안드로이드 앱 개발자에게 공개적으로 제공되는 API이다. 자세한 내용은 안드로이드 API 레퍼런스 문서를 참고한다.
앱이 기반하는 자바 클래스, 인터페이스, 기타 사전 컴파일된 코드 그룹이다. 프레임워크의 일부는 Android API를 사용하여 공개적으로 액세스할 수 있다. 그 외의 프레임워크 부분은 시스템 API 사용을 통해 OEM에만 제공한다. 안드로이드 프레임워크 코드는 앱의 프로세스 내에서 실행 된다.
시스템 서비스는 system_server, SurfaceFlinger, MediaService와 같은 집중된 모듈식 구성 요소이다. 안드로이드 프레임워크 API로 의해 노출된 기능은 시스템 서비스와 통신하여 기본 하드웨어에 액세스한다.
AOSP에서 제공하는 자바 런타임 환경이다. ART는 앱의 바이트 코들르 기기의 런타임 환경에서 실행되는 프로세스별 명령을 변환한다.
JVM과 안드로이드
달빅 가상 머신(Dalvik virtual machine)


안드로이드 런타임(ART/Android Runtime)

달빅의 JIT의 단점을 개선하기 위한 가상머신이다.
ART는 32비트 64비트 둘 다 지원한다.
ART는 JIT 컴파일와 인터프리터 대신 AOT/Ahead of Time 컴파일 전략을 사용한다.
ART는 런타임시 코드를 해석하는 대신 앱을 실행하기 전에 코드를 컴파일하여 스토리지에 저장하고 앱이 실행 중일 때 스토리지에서 램으로 불러온다.
이 접근 방식은 기존 방식보다 런타임 성능 20배 더 빠르다.
ART는 dex 바이트 코드가 매번 해석되지 않기 때문에 달빅에 비해 배터리 성능을 크게 향상시켰다.
달빅은 응용 프로그램의 시작 시간이 더 느리고 ART는 AOT 덕분에 네이티브 코드를 실행할 수 있어서 매우 빠르다.
ART는 달빅보다 가비지 컬렉션이 더 뛰어나다.
ART는 초기 RAM 사용량이 높다.
APK 설치하려면 해당 앱을 기계어로 변환하기 때문에 앱 설치 시간이 오래걸리고 설치 공간이 달빅에 비해 1.5~2배가 필요하다.
시스템 업데이트가 되었다면 기존에 설치된 모든 앱을 다시 최적화/컴파일한다.
- 안드로이드 시스템 라이브러리나 프레임워크가 변경되면 기존에 설치된 앱이 더 이상 호환되지 않을 수 있다.

현재의 ART


이 레이어의 네이티브 데몬에는 init, healthd, logd, storaged가 포함된다. 이러한 데몬은 커널 또는 다른 인터페이스와 직접 상호작용하며 사용자 공간을 기반으로 하는 HAL 구현에 의존하지 않는다.
이 레이어의 네이티브 라이브러리에는 libc, liblog, libutils, libbinder, libselinux가 있다. 이러한 네이티브 라이브러리는 커널 또는 다른 인터페이스와 직접 상호작용하며 사용자 공간을 기반으로 하는 HAL 구현에 의존하지 않는다.
HAL은 하드웨어 공급업체에서 구현할 표준 인터페이스가 포함된 추상화 계층이다. HAL을 사용하면 안드로이드가 하위 수준의 드라이버 구현을 고려하지 않아도 된다. HAL을 사용하면 상위 수준 시스템에 영향을 주거나 수정하지 않고도 기능을 구현할 수 있다. 자세한 내용은 HAL 개요를 참고한다.
커널은 모든 운영체제의 중심이며 기기의 기본 하드웨어와 통신한다. 하드웨어적인 설정을 리눅스 커널에서 관리한다. 가능한 경우 AOSP 커널은 하드웨어 제약이 없는 모듈과 공급업체별 모듈로 분할된다. 정의를 비롯하여 AOSP 커널 구성요소에 관한 자세한 내용은 커널 개요를 참고한다.
안드로이드 스튜디오의 빌드 시스템은 Gradle이고 그 플러그인 Android Gradle Plugin(AGP)는 안드로이드 앱을 빌드하는 과정을 내부적으로 처리해준다.
빌드는 결국 프로젝트를 APK와 AAB로 변환하는 과정이다.

APK와 AAB의 차이점


APK(Android Package)는 이미 완성된 안드로이드 앱 파일이고, AAB(Android App Bundle)는 APK를 완성해주는 요소를 담은 패키지다.
기존처럼 모든 기기에 대응할 수 있는 하나의 APK를 전달하는 것이 아니라, 개발자가 스토에 AAB 패키지를 올려놓으면, 스토어가 사용자 기기에 어떤 내요잉 필요한지 확인하고 그에 맞춘 APK 파일을 만들어 배포한다.
현재 구글 플레이스토에서 AAB가 의무화 되었다.
애플리케이션의 리소스 파일들은 AAPT(Android Asset Packging Tool)에 의해 해당 리소스 파일을 참조할 수 있는 ID가 부여되어 R.java 클래스 안에 담기게 된다.
AIDL은 안드로이드 플랫폼에서 서로 다른 프로세스 간에 통신하기 위해 사용되는 인터페이스 정의 언어이다.
AIDL을 사용하여 서로 다른 앱 또는 프로세스 사이에서 데이터와 메소드를 주고받을 수 있다.
AIDL 언어는 자바 언어에 기반한다.
개발자가 작성한 자바, 코틀리의 소스코드, R.java, Java Interfaces는 자바 컴파일러, 코틀린 컴파일러를 통해 자바 바이트코드인 .class파일로 변환된다.
변횐된 .class 파일과 서드 파티 라이브러리 파일을 .dex(Dalvik Executable)파일로 변환한다.
.dex 파일로 변환은 안드로이드 앱의 최적화 및 보안 강화를 위한 중요한 단계이다.
Code shrinking(코드 수축) : 소스코드나 라이브러리의 코드에서 실제로 사용되지 않은 클래스들, 필드들, 메소드들, 속성드를 제거한다.
Resource shrinking(자원 수축) : 사용되지 않은 리소스들을 제거한다. Code shrinking이 진행된 후에 진행하는 것이 유리하다. Code shrinking이 끝난 후에 어떤 리소스들을 참조되며 사용할 지를 정확히 판단할 수 있다.
Obfuscation(난독화) : 난독화는 앱의 코드를 의도적으로 어렵게 만들어서 앱을 리버싱으로 부터 보호하고 코드의 가독성을 낮추는 작업이다. 다만 이런 난독화 과정을 거치고 나면 Crash가 나거나 우리가 알아볼 수 없게 된다. 그렇기 때문에 난독화 도구는 난독화를 수행할 때 매핑 파일을 생성해준다. R8 컴파일러는 mapping.txt 라는 파일을 생성한다.
MultiDex(멀티 덱스) : 안드로이드 앱이 커질수록 단일 .dex 파일에 모든 클래스를 포함하기 어려울 수 있다. 멀티 덱스 기능을 통해 여러 개의 .dex 파일을 사용할 수 있다. 여러 개로 나뉘어 앱 실행 시 필요한 부분만 로딩하여 메모리 절약을 할 수 있다.
Optimization(최적화) : 코드를 분석해서 최종 APK파일의 크기를 줄이는 최적화를 할 수 있다. ex) R8 컴파일러는 절대 수행 될 수 없는 else문을 스스로 제거해서 최적화를 진행해준다.
위 과정을 진행하게 도와주는 도구는 Proguard와 R8이 있다.

Proguard는 .class파일을 dex파일로 변환하는 도구이다.

desugar는 자바 8이상의 기능을 지원하기 위해 이전 안드로이드 버전에서 사용할 수 없었던 새로운 자바 기능을 대체하거나 변환하는 과정이다.
이 과정의 가장 큰 단점이 더 긴 빌드 시간이다.
앞선 문제를 해결하기 위해 안드로이드 스튜디오 3.2에서 구글은 Dex 컴파일러를 D8이라는 새로운 컴파일러를 도입했다. 특징은 desugaring 변환을 제거하고 이를 .class2dex 컴파일의 일부로 만들어 빌드 시간을 더 빠르게 만드는 것이다.

R8은 D8의 파생 버전이다. 둘이 같은 코드베이스를 공유한다. 또한 R8은 추가적인 문제를 해결한다. D8과 마찬가지로 R8은 오래된 달빅/ART에서 새로운 Java 기능을 사용할 수 있게 해준다. R8의 가장 큰 장점은 앱에서 특정 디바이스나 API 레벨을 지원하기 위해 필요한 opcodes만 남기고 .dex 코드를 최적화하는 것이다.

.apk로 패키징한다.
Jarsigner는 Java 아카이브(JAR) 파일을 디지털 서명하는 데 사용되던 도구
debug 또는 release용 keystore로 signing한다.
Zipalign은 APK 파일을 최적화하여 메모리 사용을 개선하는 도구. APK 안의 파일을 4바이트 경계에 정렬하여 앱이 더 효율적으로 메모리에 로드되도록 돕는다.
zipalign tool을 이용해 align시킨다.

!https://blog.kakaocdn.net/dn/kzwME/btrgijqGKkA/rDMrTKkCJapVFTz1EHkrl1/img.png