| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- ktor-auth
- 양과 늑대
- 2022 kakao blind
- genarics
- JCF
- State
- snapshotflow
- compose
- derivedstateof
- mutableStateOf
- Java
- producestate
- remembercoroutinescope
- NavHost
- clean coder
- 선언형ui
- gradle jdk
- rememberupdatedstate
- android
- mutablestate
- apollo3
- 2022 KAKAO BLIND RECRUITMENT
- 2989번
- 선언형 ui
- bottomscaffold
- 무선 페어링
- 안드로이드
- 자바
- 명령형ui
- 명령형 ui
- Today
- Total
버미
[안드로이드] ABB와 APK 본문
ABB(.abb)와 APK(.apk)는 둘 다 파일의 배포를 위한 형식이다. 이 둘의 특징은 무엇이며 어떤 차이가 있는지 알아보자.
APK
Android Application Package의 약자로, 안드로이드에서 앱을 설치·실행하기 위한 배포 형식의 파일이다.
APK 포함 내용
이 내부에는 앱의 모든 리소스(① 해상도/픽셀에 맞춘 이미지와 리소스 세트, ② UI에 표시되는 번역된 문자열, ③ ABI 등)을 하나의 파일에 포함된다.
- 해상도/픽셀에 맞춘 이미지와 리소스 세트
필요한 PNG, JEPG, SVG 파일을 Drawable에 추가하는데, 해당도에 따라 mdpi ~ xxxhdpi까지 리소스가 만들어진다. - UI에 표시되는 번역된 문자열
UI에 표시되는 문자열이 번역된다. 기본 언어인 영어, 일본어, 프랑스어 등 앱이 지원하는 모든 언어 버전의 문자열 리소스가 들어간다. APK 크기가 커지는 이유 중 하나. - ABI (Application Binary Interface)
어떤 종류의 CPU에서 실행할수 있는 코드인지 결정하는 규격이다. APK에는 모든 ABI 별 .so 파일이 들어간다.
하지만 기기에서는 자기 CPI 아키텍처에 맞는 라이브러리만 사용한다.
구형 ARM 기기 - 32비트 ARM - armeabi-v7a
최신 안드로이드 기기 - 64비트 ARM - arm64-v8a
에뮬레이터, 일부 태블릿 - 32비트 Intel - x86
일부 고성능 기기, 에뮬레이터 - 64비트 Inter - x86_64
APK 생성 과정
생성 과정을 요약하면 다음과 같다. 소스 코드 작성 -> 컴파일 -> 패키징 -> 서명 & 정렬 & 최적화를 통해 최종 산출
- 소스 코드 작성
Java/Kotlin 소스 코드, 레이아웃 XML, 리소스 이미지, 문자열, 네이티브 코드(C/C++)가 있다면 .cpp/.c 파일 - 컴파일
- Java/Kotlin -> .class → .dex
javac/kotlinc로 .class 생성 -> D8/R8로 .dex (Dalvik/ART 바이트 코드) 생성 - 리소스(XML/이미지/문자열 등) → 바이너리 소스
aapt2 가 레이아웃/values XML은 바이너리 XML를 생성, R 클래스 상수 생성(리소스 ID 매핑), PNG/Webp 등은 필요시 압축/최적화되어 포함 - 네이티브 코드(C/C++) → .so
NDK(CMake/ndk-build)로 ABI 별 .so 컴파일
- Java/Kotlin -> .class → .dex
- 패키징
각 산출물은 묶는다. 그 결과 Unsigned APK가 생성된다. classes.dex(여러 개 일 수 있음), res/*(바이너리 리소스), AndroidManifext.xml(바이너리), lib//*.so, assets/*, META-INF(메타데이터) 등을 ZIP 구조로 묶고 확장자를 .apk로 지정 - 서명 & 정렬 & 최적화
디버그/릴리스 키로 APK를 서명, zipalign으로 APK내부 데이터를 정렬, (선택) R8/ProGuard 난독화 - 최종 산출
스토어/사이드로딩에 APK 배포
APK 설치 과정
APK는 설치 시 압축 해제되고, classes.dex (Java/Kotlin 코드), 리소스, 네이티브 라이브러리 등이 OS에 등록된다.
- APK 다운로드 / 전달
Google Play, 타 앱 스토어 또는 직접 설치 - 서명 검증
OS가 APK의 서명을 검사
서명이 잘못되면 설치 불가 - 패키지 매니저가 APK를 /data/app/ 경로에 풀어서 저장
- DEX 최적화 (OAT / ART)
APK의 안의 classes.dex를 기기용 네이티브 코드로 변환 - 리소스/라이브러리 등록
resources.arsc (리소스 인덱스), .so(네이티브 라이브러리) 준비
앱 실행 과정 (런타임)
앱 실행 과정을 요약하면 다음과 같다. AMS → Zygote fork → ART DEX 로드 & so 로드 → Application 생성 → MainActivity 실행
- Launcher -> ActivityManagerService(AMS) 호출
홈 런처 앱이 인텐트 발송
AMS가 어떤 앱을 실행할지 확인 - 새 프로세스 생성
해당 앱의 UID, 프로세스 이름으로 Zygote 프로세스를 포크
Zygote = 안드로이드 앱 프로세스 생성용 부모 프로세스 (공통 라이브러리 미리 로드) - 앱 초기화
안드로이드 런타임(ART)이 classes.dex 로드
필요한 .so 라이브러리 로드
리소스 매니저(ResourceManager)가 리소스 ID를 매핑 - Application 객체 생성
Application.onCreate() 호출 -> 앱 전역 초기화 - 첫 Activity 실행
인텐트에 따라 MainActivity.onCreate() 실행
레이아웃 XML이 View 객체로 Inflate되어 UI 구성 - UI 표시 & 이벤트 루프 시작
메인 스레드(Looper)가 이벤트를 처리하며 UI가 동작
APK가 앱 배포를 위한 최적의 구조였다면 ABB가 나오지 않았을 것이다.
APK의 한계는 다음과 같다.
- 모든 리소스를 한 파일에 포함하여 용량 낭비
APK에는 해상도/픽셀에 맞춘 이미지와 리소스 세트, UI에 표시되는 번역된 문자열, ABI가 전부 포함된다. - 업데이트 시 전체 APK 재다운로드
작은 수정에도 전체 APK를 새로 받아야 한다.
따라서, 데이터 소모, 업데이트 속도 문제 발생 - 멀티 APK 관리 어려움
기기별로 APK를 따로 만들고 관리하려면 개발자가 직접 빌드/업로드 해야 한다.
스토어 관리, 버전 제어가 복잡하다.
위의 APK 한계를 뛰어넘고자 AAB가 등장했다.
AAB
Android App Bundle의 약자로 2018년 Google이 도입한 앱 배포용 패키징 형식이다. 핵심 아이디어는 앱의 모든 코드와 리소스를 하나로 묶어서 업로드하면, Google Play가 사용자 기기에 맞는 APK를 자동 생성·배포하는 것이다.
AAB 포함 내용
APK가 기존에 포함하고 있던 항목(해상도/픽셀에 맞춘 이미지와 리소스 세트, UI에 표시될 번역된 문자열, ABI)에 더해, BUNDLE-METADATA, 원본 리소스 압축 전 상태가 들어가있다.
- 해상도/픽셀에 맞춘 이미지와 리소스 세트
- UI에 표시될 번역된 문자열
- ABI
- BUNDLE-METADATA
빌드 환경 정보, ProGuard/R8 매핑 파일, 서명 관련 메타데이터 - 원본 리소스 압축 전 상태
APK 생성 전에 최적화·분리가 가능하도록 원본 상태로 보관한다. 새 DPI 그룹이 필요하다던가, 새 CPU 아키텍처가 나왔을 때, 원본 리소스를 담고 있으면 그 형식에 맞춰 컴파일할 수 있기 때문에 이 항목이 필요하다.
AAB 생성 과정
APK의 1, 2단계까지는 동일하다. 생성 과정을 요약하면 다음과 같다. 소스 코드 작성 -> 컴파일 -> 패키징 -> 서명 & 정렬 & 최적화를 통해 최종 산출.
- 소스 코드 작성
Java/Kotlin 소스 코드, 레이아웃 XML, 리소스 이미지, 문자열, 네이티브 코드(C/C++)가 있다면 .cpp/.c 파일 - 컴파일
- Java/Kotlin -> .class → .dex
javac/kotlinc로 .class 생성 -> D8/R8로 .dex (Dalvik/ART 바이트 코드) 생성 - 리소스(XML/이미지/문자열 등) → 바이너리 소스
aapt2 가 레이아웃/values XML은 바이너리 XML를 생성, R 클래스 상수 생성(리소스 ID 매핑), PNG/Webp 등은 필요시 압축/최적화되어 포함 - 네이티브 코드(C/C++) → .so
NDK(CMake/ndk-build)로 ABI 별 .so 컴파일
- Java/Kotlin -> .class → .dex
- 번들링(패키징)
Base Module(필수 코드/리소스)와 Dynamic Feature modules(선택 다운로드 기능)을 포함
언어별, 화면 밀도별, ABI별 Config splits 정보를 함께 구조화
실행 가능한 단일 APK가 아니라, APK 생성에 필요한 모든 코드·리소스를 모듈화하여 저장한다.
base/ (필수 모듈)
- dex/
- res/
- manifest/
- lib/<ABI>/
- assets/
- resources.pb
feature_xxx/ (동적 기능 모듈)
BUNDLE-METADATA/ (빌드/분할/서명 관련 메타데이터) - 서명
로컬 빌드 시 개발자 키로 서명이 가능하지만, Play Store 배포 시에는 Play App Signing이 최종 서명을 처리한다. 서명 정보는 BUNDLE-METADATA 안에 포함한다. - 최적화
R8/ProGuard 로 코드 난독화 및 불필요 코드 제거
리소스 쉬링크로 미사용 리소스 제거 가능
구글 플레이가 기기별 APK 생성 시 압축·최적화 처리 가능하도록하여 압축은 최소화 - 최종 산출
자체 실행은 불가하며 APK 변환 필수
Google Play Console 업로드하여 play가 기기 맞춤 APK 생성 후 배포 또는 bundletool로 로컬에서 기기 맞춤 APK 생성
서명된 AAB 만들기
1. Build 탭 클릭

2. Generate Signed App Bundle /APK... 클릭

3. Android App Bundle(AAB) 활성화하여 Next

4. (Key Store가 없다면) Create new... 클릭

5. Uploac Key 및 Key Store 생성

Key Store(키 저장소)
- Key Store Path : 키 저장소를 생성할 위치(.jks 확장자 사용)
- Password : 키 저장소에 사용할 보안 비밀번호를 생성
- Confirm : Password와 같은 값
Key(키)
- Alias : 키를 식별할 수 있는 이름
- Password : 키에 사용할 보안 비밀번호. 해당 비밀번호는 Key Store(키 저장소) 비밀번호와 동일하게 작성한다면, 유지보수/자동화(CI/CD)에서 스크립트 관리가 간편하다. 키스토어는 빌드 서버 여러 명이 접근 가능하지만, 서명 키는 소수만 사용 가능하게 하려는 경우는 다르게 작성해도 된다.
- Validity (years) : 키가 유효하게 유지되는 기간(년)을 설정한다. 평생 서비스 고려하여 키를 최소 25년 ~ 100년으로 설정.
- Certificate : 소유자 정보를 입력하는 부분이다. 이 정보는 앱을 서명할 때 APK/AAB의 인증서 메타데이터에 포함된다.
서명되지 않은 AAB
이전 섹션에서는 서명된 AAB를 만드는 단계를 보여줬지만, 2번 째 단계항목에서 서명되지 않은 AAB를 만들 수도 있다.
이는 AAB에 대한 후 처리를 하는 경우 필요하다. 전용 서명 서버에서만 서명하여 보안을 강화하거나 마켓이나 파트너별로 다른 키로 서명을 요구해, 원본 AAB 하나로 다양한 서명 라인에 투입이 가능하다.
'안드로이드' 카테고리의 다른 글
| [안드로이드] Gson과 kotlinx.serialization 차이 (0) | 2025.09.23 |
|---|---|
| [안드로이드] Gradle 이란 (0) | 2025.09.16 |
| [안드로이드] ANR (0) | 2025.07.22 |
| [안드로이드] Compose Navigation 개괄적 이해 (0) | 2025.07.09 |
| [안드로이드] API 35 버전 업데이트 정리 (0) | 2025.06.28 |