본문 바로가기
안드로이드/Android

[Android] 빌드, MultiDex

by jinwo_o 2024. 11. 30.

빌드

  • 개발자가 소스 코드를 작성 후 앱 설치 파일 APK 를 만들기까지의 실행 과정

 

리눅스에서의 빌드

  • 소스 코드를 컴퓨터가 읽을 수 있는 기계어로 번역(*컴파일)하고, 내가 만든 소스 코드에서 사용하는 라이브러리와 연결해서 최종 실행 파일 형태로 만드는 것
    • 컴파일(Compile) : 사람이 읽을 수 있는 형태의 소스 코드를 컴퓨터가 읽을 수 있는 형태의 기계어로 변환해 주는 과정

 

JVM 에서의 빌드

  • JVM(Java Virtual Machine) : 자바는 OS 에 종속적이지 않다는 특징을 가지고 있다. OS 에 종속받지 않고 실행되기 위해서는 OS 위에서 자바를 실행할 수 있는 환경이 필요하다. JVM 은 자바 바이트 코드를 운영체제에 종속되지 않고 실행할 수 있도록 해주는 역할을 한다.

  • .class 자바 클래스 파일 : *JVM 에서 실행 가능한 자바 바이트 코드(JVM 의 명령어 세트)를 포함하는 파일
  • JAR(Java Archive) : 여러 개의 자바 클래스 파일과 클래스들이 이용하는 관련 리소스(텍스트, 그림 등) 및 메타데이터를 하나의 파일로 모아서 자바 플랫폼에 응용 소프트웨어나 라이브러리를 배포하기 위한 소프트웨어 패키지 파일 포맷
  • Kotlin runtime : 코틀린 자체 표준 라이브러리 클래스와 자바 API 의 기능을 확장한 내용이 들어있다. 코틀린 컴파일러로 컴파일한 코드는 코틀린 런타임 라이브러리에 의존성을 가지기 때문에 애플리케이션을 배포할 때는 코틀린 런타임을 넣어 같이 배포한다.

 

Kotlin 과 Java 가 함께 있을 때의 컴파일 과정

  1. Kotlin 컴파일러가 Kotlin 코드를 컴파일해 .class 파일을 생성한다. 이 과정에서 Kotlin 코드가 참조하는 Java 코드가 함께 로딩되어 사용된다.
  2. Java 컴파일러가 Java 코드를 컴파일해 .class 파일을 생성한다. 이때 이미 Kotlin 이 컴파일한 .class 파일의 경로를 클래스 패스에 추가해 컴파일한다.
    • 주의 : Kotlin 은 이미 컴파일된 단계에서 Java 컴파일이 이루어지기 때문에, Kotlin 코드에서 Java Annotation 프로세서로 생성되는 코드를 사용하면 문제가 발생한다.

 

안드로이드에서의 빌드

  • 빌드 프로세스는 Gradle *빌드 도구가 수행한다.
    • 빌드 도구 : 외부 라이브러리 추가 및 업데이트 등의 설정 시간을 단축시키고, 테스트 실행 및 호환성 체크까지 진행한다.
      • 안드로이드에서 사용되는 빌드 도구는 mavengradle 등이 있으며 구글에서는 gradle 의 사용을 권장하고 있다.
      • Gradle 내부의 빌드 스크립트를 작성하여 앱의 의존성, 라이브러리, 리소스 파일, 빌드 설정 등을 진행한다.
  • 빌드 프로세스는 앱의 소스 코드와 빌드 스크립트를 결합하여 APK 파일을 생성한다.

1. 코틀린 컴파일러는 .kt 파일을 .class 바이트 코드 파일로 변환한다.

2. Android SDK 의 DX 도구를 사용하여 .class 파일들을 .dex 파일로 변환한다.

3. 안드로이드 리소스 패키징 도구(aapt)와 Gradle 사용하여 리소스 파일 및 외부 라이브러리 모듈을 .dex 파일과 함께 APK 파일로 패키징 한다.

4. APK 파일은 서명되어야 안드로이드 디바이스에서 실행될 수 있다. APK 파일에 서명하기 위해서는 디지털 인증서를 사용해야 한다. APK 파일에 서명하는 작업은 빌드 과정에서 Gradle 에 설정된 값에 따라 자동으로 수행한다.

 

APK 설치 및 실행

  • 설치된 APK 는 안드로이드 런타임 과정을 따라 초기 JIT 방식을 활용하여 앱을 설치한 후, 이후 자주 사용하는 앱을 AOT 방식을 활용하여 컴파일하는 방식으로 진행된다.
    • JIT(Just In Time) : 실행되는 시점에 필요한 코드만 컴파일하여 실행하는 방식으로, 런타임 중에 컴파일을 진행하여 런타임이 느리게 동작할 수 있다. 화면 전환 및 앱이 실행될 때마다 코드를 컴파일한다.
    • AOT(Ahead Of Time) : 애플리케이션이 설치되는 시점에 코드를 컴파일하고 미리 캐시 하여 실행하는 방식으로, 애플리케이션 실행 속도가 빠르다.
  • 각각의 컴파일 방식의 장단점을 해소하기 위해 이렇게 컴파일을 2번 진행한다.
    • AOT 컴파일은 앱 설치 시 모든 코드를 미리 컴파일하기 때문에 실행 속도가 빠르지만, 컴파일된 파일이 디스크 공간을 많이 차지해 설치 가능한 앱의 수가 제한될 수 있다. 반면, JIT 컴파일은 실행 시 필요한 코드만 컴파일되기 때문에 초기 성능에 영향을 줄 수 있지만, 한 번 컴파일된 이후에는 AOT 와 비슷한 속도를 낼 수 있으며, 디스크 용량을 적게 차지한다.

 

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

  • 과거에 구글은 많은 사용자들이 사용하는 Java 를 기반으로 앱 개발을 지원했지만, 라이센스 문제와 메모리 효율성 문제로 인해 일반 JVM 환경 대신 Dalvik VM 을 선택하게 되었다.

Dalvik

  • Android 2.1부터 5.1까지 사용되었던 런타임 환경
  • JIT 컴파일러를 사용한다.
  • 앱이 실행되는 순간 자주 사용되는 바이트 코드를 컴파일하여 Machine Code 로 변환 후 캐싱하여 RAM 에 올린다.
  • 앱 실행 중 latency(지연 시간)가 발생한다.
  • ART 에 기반에 설치 속도가 매우 빠르다.
  • 컴파일이 빈번하게 일어나기에 배터리 소모 및 RAM 사용량이 높다.
  • .dex 파일을 dexopt 툴을 이용해 .odex 파일로 변형한 뒤 DVM 에서 JIT 컴파일러로 .odex 파일을 기계어로 번역한다. 변환된 기계어는 RAM 에 올려지어 사용된다.

 

ART

  • Android 4.4부터 현재까지 적용되는 런타임 환경
  • AOT 컴파일러를 사용한다.
  • 앱 설치 시 모든 코드를 Machine Code 로 컴파일하여 앱 패키지 안에 저장하기 때문에 설치 속도가 느리다.
  • 앱 실행 시 컴파일을 하지 않아도 되기에 JIT 의 지연시간이 없다.
  • 미리 컴파일 후 odexelf 파일 등을 모두 모은 aot 파일을 저장하기 때문에 용량이 크다.
  • .dex 파일을 dex2oat 툴을 이용해 .dex -> .odex -> .oat 파일로 변형한 뒤 OAT 컴파일러로 .oat 파일을 기계어로 번역한다.
  • .oat 파일은 .dex 파일 + .odex 파일 + elf 파일(실행 파일) 형식의 기계어를 포함하고 있어 용량이 크다.

MultiDex

  • 안드로이드 플랫폼에서 애플리케이션을 실행하는 데 사용되는 *DEX 파일 형식의 *한계를 극복하기 위해 도입된 메커니즘
    • DEX(Dalvik Executable) : 코틀린 컴파일러가 .kt 파일을 .class 자바 바이트 코드로 변환한 후, 이 변환된 .class 파일들을 하나로 합쳐 생성한 실행 파일
    • 한계 : 엡에 API 20 이하 minSdk 가 있고, 앱과 앱이 참조하는 라이브러리에서 메서드가 65,536(64K)개를 초과하면 앱이 Android 빌드 아키텍처의 제한에 도달했음을 나타내는 빌드 오류가 발생한다.
      • 즉, 단일 DEX 바이트 코드 파일 내에서 참조할 수 있는 메서드의 총 개수를 초과하였다.
  • Multidex 를 사용하면 애플리케이션이 두 개 이상의 DEX 파일을 가질 수 있다. 이를 통해 애플리케이션에 더 많은 메서드를 포함할 수 있으므로 메서드 수 제한이 방지된다.
  • 기본 DEX 파일에 어떤 클래스를 포함하고 보조 DEX 파일에 어떤 클래스를 포함할지에 대한 복잡한 결정은 빌드 시스템에서 이루어지므로, 멀티덱스 구성에는 상당한 빌드 시간이 소요될 수 있다. 일반적으로 멀티덱스를 사용하는 증분 빌드는 시간이 더 걸리며, 개발 프로세스를 지연시킬 가능성이 있다.
    • 더 긴 증분 빌드 시간을 완화하려면 사전 덱싱을 사용하여 빌드 간에 Multidex 출력을 재사용해야 한다. 사전 덱싱을 사용하려면 Android 5.0 이상에서만 사용할 수 있는 ART 형식이 필요하다.
  • 64K 개 이상의 메서드 참조를 사용하도록 앱을 구성하기 전에 앱 코드가 호출하는 참조의 총 개수를 줄이는 단계를 먼저 진행한다.
    • 앱의 직접 종속 항목과 전이 종속 항목 검토 : 앱에 포함되는 큰 라이브러리 종속 항목이 앱에 추가되는 코드 양을 초과하는지 고려한다.
    • R8 로 사용되지 않는 코드 삭제 : 코드 축소를 활성화하여 출시 빌드에서 R8 을 실행한다. 축소를 활성화하면 사용되지 않는 코드와 리소스를 APK 에 포함하지 않을 수 있다.

 

  • Android 5.0(API 수준 21) 이전의 플랫폼 버전에서는 앱 코드를 실행하기 위해 Dalvik 런타임을 사용한다. 기본적으로 Dalvik 에서는 APK 당 하나의 classes.dex 바이트 코드 파일로 앱을 제한한다. 이 제한을 우회하려면 *멀티덱스 라이브러리를 사용해야 한다.
    • 이제 앱을 빌드할 때 Android 빌드 도구는 기본 DEX 파일(classes.dex)과 보조 DEX 파일(classes2.dex, calsses3.dex 등)을 필요에 따라 구성한다. 그 후 빌드 시스템이 모든 DEX 파일을 APK 로 패키징한다.
      • 런타임에서는 기본 classes.dex 파일만 검색하는 대신, 멀티덱스 API 는 특별한 클래스 로더를 사용하여 메서드에서 사용할 수 있는 모든 DEX 파일을 검색한다.
 

메서드가 64K개를 초과하는 앱에 관해 멀티덱스 사용 설정  |  Android Studio  |  Android Developers

앱이 여러 DEX 파일을 빌드하고 읽을 수 있도록 하는 멀티덱스 앱 구성의 사용 방법에 관해 알아보세요.

developer.android.com

  • Android 5.0(API 수준 21) 이상에서는 ART 런타임을 사용한다. 기본적으로 ART 는 APK 파일에서 여러 개의 DEX 파일을 로드하는 것을 지원한다. 앱 설치 시 사전 컴파일을 실행하여 classesN.dex 파일을 스캔하고 Android 기기에서 실행할 수 있는 단일 OAT 파일로 컴파일한다.
    • 즉, minSdkVersion 이 21 이상이라면 멀티덱스가 기본적으로 사용 설정되며 멀티덱스 라이브러리가 필요하지 않다.

 

[Android] 안드로이드의 빌드 과정

빌드와 빌드 도구 그리고 빌드 과정에 대하여

velog.io

 

[안드로이드 아키텍처] 소스 코드는 어떻게 앱이 되고 스마트폰에서 실행될까?

안드로이드 아키텍처는 플랫폼의 실제적인 동작 구조 또는 형태를 말합니다. 작성한 소스 코드가 디바이스에 설치되면 이 아키텍처 구조 안에서 모든 동작이 결정됩니다.코드는 어떻게 앱으로

www.hanbit.co.kr

 

안드로이드 빌드 과정(Android APK build process)를 이해하자!

1. Complier 이란 무엇일까?컴파일러(compiler 해석기, 번역기)는 특정 프로그래밍 언어로 쓰여 있는 문서를 다른 프로그래밍 언어로 옮기는 언어 번역 프로그램을 말한다. 컴파일러는 고급 프로그

hik-coding.tistory.com

 

[Android] Android Runtime환경 ART와 Dalvik

Android의 런타임 환경인 Dalvik과 ART에 관하여

velog.io

 

메서드가 64K개를 초과하는 앱에 관해 멀티덱스 사용 설정  |  Android Studio  |  Android Developers

앱이 여러 DEX 파일을 빌드하고 읽을 수 있도록 하는 멀티덱스 앱 구성의 사용 방법에 관해 알아보세요.

developer.android.com

https://d2.naver.com/helloworld/6685007