Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536Các hệ thông mới hơn sẽ có dạng:
trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option.Cả hai thông báo lỗi này đều hiển thị con số 65536. Đây là con số thể hiện tổng số tham chiếu tối đa mà có thể được gọi bằng code trong một file Dalvik executable (dex) byte code.
Giới hạn 65k tham chiếu
Ứng dụng Android chứa Dalvik executable file (dex) trong đó chứa mã nguồn và tài nguyên dùng để chạy chương trình. Đặc tả kỹ thuật của file dex giới hạn tối đa 65536 phương thức mà có thể được tham chiếu trong một file dex, bao gồm các method của Android framework, của thư viện bên thứ 3, và của mã nguồn chương trình. Để có thể build ứng dụng vượt quá con số này, bạn phải cấu hình quá trình build để tạo ra nhiều file dex, hay còn được gọi là cấu hình multidex.
Multidex với nền tảng Android dưới 5.0
Các phiên bản Android dưới 5.0 sử dụng Dalvik runtime để chạy app code. Mặc định, Dalvik giới hạn app với một file dex duy nhất cho một file APK. Để có thể loại bỏ giới hạn này bạn có thể sử dụng thứ viện multidex support library. Thư viện này sẽ trở thành một phần trong file dex chính, và quản lý việc truy cập vào các file dex còn lại của ứng dụng.
Multidex với Android 5.0 trở lên
Android 5.0 trở lên sử dụng runtime được gọi là ART mặc định hỗ trợ load nhiều file dex từ file APK. ART thực thi compile trước (pre-compilation) tại thời điểm cài đặt ứng dụng, scan các file class(....N).dex và compile chúng thành một file .oat duy nhất, file này được thực thi bởi thiết bị Android.
Cách tránh vượt quá 65k
Trước khi cấu hình cho phép app vượt quá 65k tham chiếu bạn cần phải thực hiện các bước giảm số lượng tham chiếu được gọi trong app code, bao gồm được gọi trọng mã nguồn app và các thư viện. Có hai chiến thuật giúp bạn đạt được điều này
- Xem xét lại các dependency trực tiếp hoặc bắc cầu: tránh add dependency các thư viện lớn mà chỉ sử dụng một vài phương thức trong đó.
- Xoá các code không sử dụng bằng proguard: cấu hình để app chạy proguard.
Cấu hình app multidex với Gradle
Plugin Android cho Gradle có trong bộ Android build tool 21.1 trở lên hỗ trợ multidex. File build gradle được cấu hình như sau:
android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.0' }
Chú ý: có thể cấu hình multiDexEnable ở trong defaultConfig, buildType, và productFlavor.
Trong file AndroidManifest thêm class MultidexApplication từ thư viện multidex support library vào application element.
Chú ý: nếu ứng dụng có sử dụng một custom Application class, bạn có thể ghi đề phương thức attachBaseContext() và gọi hàm Multidex.install(this) để enable multidex.
Bạn có thể sử dụng biến thể devDebug có những thuộc tính của dev productFlavors và debug buidType. Sẽ cho thời gian build nhanh hơn vì Android 5.0 hỗ trợ multidex sử dụng ART.
Trong file AndroidManifest thêm class MultidexApplication từ thư viện multidex support library vào application element.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application> </manifest>Sau khi thêm các cấu hình trên, công cụ build Android sẽ tạo ra một file dex(classes.dex) chính, các file dex(classes2.dex, classes3.dex) phụ nếu cần thiết.
Chú ý: nếu ứng dụng có sử dụng một custom Application class, bạn có thể ghi đề phương thức attachBaseContext() và gọi hàm Multidex.install(this) để enable multidex.
Các giới hạn của thư viện support multidex
- Việc cài đặt nhiều file .dex lên device rất phức tạp và có thể dấn tới Application Not Responding (ANR) trong trường hợp file .dex thứ hai quá lớn. Trong trường hợp này bạn phải áp dụng các kỹ thuật thu gọn mã nguồn bằng cách sử dụng proGuard để tối ưu kích thước của các dex file, và loại bỏ các mã không dùng tới
- Các ứng dụng sử dụng multidex có thể không chạy được trên các máy sử dụng nên tảng Android dưới 4.0 do lỗi linearAlloc của Dalvik issue22586. Vì vậy phải kiểm tra kĩ càng khi sử dụng multidex cho các thiết bị này.
- Các ứng dụng sử dụng multidex đòi hỏi phải cấp phát một bộ nhớ lớn có thể bị crash trong khi chạy do giới hạn linearAlloc của Dalvik issue78035. Giới hạn cấp phát đã được tăng lên từ Android 4.0 nhưng ứng dụng vẫn có thể vướt quá giới hạn này đổi với nền tảng dưới 5.0.
Tối ưu hoá build multidex
Multidex sẽ làm tăng đáng kể thời gian build bởi vì hệ thống phải đưa ra một quyết định phức tạp về class nào được đặt trong file dex chính, và class nào thì đặt trong file dex phụ.
Để giảm bớt thời gian build khi sử dụng multidex, bạn nên tạo ra hai biến thể của quá trình build. Sử dụng Android plugin của Gradle productFlavor: development flavor, và production flavor. File build được cấu hình như sau:
android { productFlavors { // Define separate dev and prod product flavors. dev { // dev utilizes minSDKVersion = 21 to allow the Android gradle plugin // to pre-dex each module and produce an APK that can be tested on // Android Lollipop without time consuming dex merging processes. minSdkVersion 21 } prod { // The actual minSdkVersion for the application. minSdkVersion 14 } } ... buildTypes { release { runProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile 'com.android.support:multidex:1.0.0' }