[펌] Android Cannot fit requested classes in a single dex file. 해결 방법
Error:Cannot fit requested classes in a single dex file.Try supplying a main-dex list. # methods: 72477 > 65536
안드로이드 빌드할 때 위와 같은 에러가 발생한다면?
minSdkVersion 이 21 이상인 경우
build.gradle 파일에서 multiDexEnable 를 true로 설정하면 됩니다.
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}
...
}
minSdkVersion 이 20 이하인 경우
build.gradle 파일에서 multiDexEnable 을 true로 설정하고 multidex 지원 라이브러리를 추가해야 합니다.
그리고 custom application을 사용하지 않는다면 MultiDexApplication을 추가해야 합니다.
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 26
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.3'
}
<application
android:name="android.support.multidex.MultiDexApplication"
...>
...
</application>
왜 이런 에러가 발생하는가?
APK 파일에는 DEX(Dalvik Executable) 파일 형식의 실행 가능한 바이트코드 파일이 포함됩니다.
단일 DEX 파일 내에서 참조할 수 있는 메서드의 총 개수를 65,636으로 제한하며 이 DEX 파일에는 프레임워크 메서드, 라이브러리 메서드, 본인 앱에서 정의한 메서드가 모두 포함됩니다. 즉 앱 내의 모든 메서드가 65,536개를 넘어서 이러한 에러가 발생한 것입니다. 64 * 1024의 값과 동일하며 이 제한을 64K 참조 제한이라고 합니다.
안드로이드 L (롤리팝, 5.0 API 21 ) 미만의 플랫폼 버전에서는 앱 코드 실행을 위해 Dalvik 런타임을 사용합니다. APK당 하나의 classes.dex 바이트코드 파일로 앱을 제한합니다. 이러한 제한을 해결하기 위해 multidex 지원 라이브러리를 사용할 수 있습니다.
안드로이드 L (롤리팝 5.0 API 21) 이상에서는 Dalvik이 아닌 ART (Android Runtime)이라는 런타임을 사용합니다. 이 런타임은 APK 파일로부터 여러 개의 DEX 파일을 로드하는 것을 지원합니다. ART는 앱 설치 시에 사전 컴파일 수행하여 classesN.dex 파일들을 스캔하고, 안드로이드 기기가 실행할 수 있도록 .oat 파일로 컴파일 합니다.
그래서 minSdkVersion 21이상이라면 multidex 지원 라이브러리가 필요없습니다. build.gradle에 간단하게 multiDexEnabled true 만 추가하면 됩니다.
multidex 속도가 느린 이유?
각 DEX 파일들을 빌드할 때 빌드 툴(buildToolsVersion)은 주 DEX 파일에 어떤 클래스들을 포함할지 고르는 아주 복잡한 의사결정을 수행하게 됩니다. 이러한 과정이 없다면 앱 실행에 필요한 클래스들이 주 DEX에 포함되어있지않아 Crash가 나기때문입니다. 그래서 이러한 과정을 거치게되는데 시간이 상당히 오래걸립니다.
네이티브 코드가 주 dex에 포함이 안되는 경우?
네이티브 코드를 사용하는 라이브러리를 포함한다고 생각해 봅시다. 그 라이브러리에서 네이티브(JNI) 코드를 사용하게되면 의사결정 과정에서 라이브러리가 구동되기위해 필요한 클래스들이 주 DEX 파일에 포함되지 않을 수 있습니다. 그럴 경우에는 multiDexKeepFile, multiDexKeepProguard 를 사용해서 주 DEX에 포함시키도록 해야합니다.
빌드 최적화
위에도 써놨듯이 multidex는 복잡한 의사결정을 수행하면서 빌드 시간이 상당히 커질 수 밖에 없습니다. 빌드 시간을 줄이기 위해서 빌드 사이에 multidex를 재사용하는 pre-dexing을 사용할 수도 있습니다. 하지만 Android 5.0 롤리팝 이상인 ART 환경에서만 가능합니다.
Android Studio 2.3 이상인 경우는 IDE에서 자동으로 pre-dexing을 사용하기 때문에 별도로 작성할 것은 없습니다. android studio와 gradle plugin은 최신버전으로 업데이트하면 빌드 속도를 최적화하는 기능들이 추가적으로 들어있기 때문에 항상 최신버전으로 유지하는 것이 좋습니다.
multidex의 알려진 문제들.
- 단말기에 DEX 파일들을 설치할 때, 두번째 DEX 파일이 클 경우에 ANR(Android Not Responding)이 발생할 수 있습니다. 이를 막기 위해서 ProGuard 에서 코드 축소(Code Shrinking)을 해야 합니다.
- Android 5.0 롤리팝 미만에서 실행할 경우 linearalloc limit (issue 78035) 이슈를 완전히 막을 수 없습니다.
출처: https://duzi077.tistory.com/198 [개발하는 두더지]
'Unity3D > Android' 카테고리의 다른 글
[버그] APP NOT CORRECTLY CONFIGURED TO USE GOOGLE PLAY GAME SERVICES (0) | 2020.02.17 |
---|---|
[펌] Android App Bundle(AAB) 빌드하기 (0) | 2020.02.11 |
[펌][Unity] Keystore 생성 (0) | 2020.01.17 |
[Link] READ_PHONE_STATE (0) | 2019.06.14 |
[펌] Remove READ_PHONE_STATE Permission Unity Android (0) | 2019.06.14 |