Compile Errors from Referencing More Than 65,000 Methods
Apps that reference close to 65,000 methods will encounter compile errors on submission to the Appstore due to Dalvid executable limits in bytecode files.
- Build errors from referencing more than 65,000 methods
- Additional methods added from Amazon's wrapper
- Counting the number of method references
- Reducing the number of method references
- Keeping the AndroidX library unobfuscated
- Additional resources
Build errors from referencing more than 65,000 methods
If you submit an app to the Amazon Appstore that references close to 65,000 methods, you may receive the following error message via email or on the App Status screen after submission:
Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
This error is caused by Android's limit of 65,535 method references for Dalvik executable (dex) bytecode files. For more information, see Enable multidex for apps with over 64K methods in the Android documentation.
Additional methods added from Amazon's wrapper
Amazon wraps every app in the Amazon Appstore with code to provide developers with various reports, analytics, DRM, and app updates. This wrapper adds 1,627 additional referenced methods for the Amazon library and 9 additional methods per activity. Because of these additional referenced methods, your app could be pushed over the method limit if it references close to 65,000 methods.
Although this limit has always existed, exceeding the method-reference limit has become more common with the release of Android 5.0 (Lollipop), which includes new features that often increases the number of method references an app might make.
To avoid this limit, considering counting the number of method references and reducing the number of references in your app.
Counting the number of method references
To count the number of the methods that your app references and what part of the app references them, you can use the dex-method-counts tool available from GitHub: https://github.com/mihaip/dex-method-counts.
Reducing the number of method references
To reduce the number of method references, try removing as many extra libraries and methods as possible. Alternately, you can use ProGuard with -dontoptimize –dontobfuscate
in the configuration, which will remove unused methods from the dex file at build time.
If the these approaches do not work for your app, try using the multi-dex approach, which splits up classes.dex
into multiple dex files.
You can use the multidex library with the Android Gradle plugin. For more information, see Enable multidex for apps with over 64K methods.
Note the following with the multidex approach:
- You must use Gradle for your Android development.
- You might find that Multidex does not remove enough methods without performing a few extra steps (outlined in the next section).
You can use the dex-method-counts tool referenced above to check the method count of your resulting classes.dex
file.
Using the multidex library
With Android 5.0 Lollipop, a support library (called android-support-multidex.jar
) appeared in Android SDK ver 21.1.x and Android Support library 21.0.3. You can find this support library in \android-sdk\extras\android\support\multidex\library\libs
. It contains two new classes — MultiDex
and MultiDexApplication
— and simplifies the multidex loading process.
You do not need to use this library if your app targets Android 5.0 exclusively because Android 5.0 has built-in support for secondary dex files. On previous versions, however, Android adds additional .dex
files from the APK archive to the classloader. The library allows the archive to become part of the primary DEX file of your app and manages access to the additional DEX files. As a result, you should use this library if your app targets any Android releases before Android 5.0.
To implement this solution for pre–Android 5.0 apps:
- Make sure you have updated your Android Build Tools to the latest version. You will need at least version 21.1.x or later.
- Add the
android-support-multidex.jar
library into your project. You can find it in\android-sdk\extras\android\support\multidex\library\libs
. -
Add
multiDexEnabled true
and a Multidex dependency to yourbuildConfig
in thebuild.gradle
file, as shown in the following example:android { compileSdkVersion 21 buildToolsVersion "21.1.2" defaultConfig { ... minSdkVersion 14 targetSdkVersion 21 ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.0' }
-
Either override the
android.app.Application
class, or declare theMultiDexApplication
class in theAndroidManifest.xml
file, as shown in the following code:<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:name="android.support.multidex.MultiDexApplication"> ... </application>
-
If you have any additional libraries in your project, be sure that you disable pre-dexing on them. Unfortunately, the
--multi-dex
option is not compatible with pre-dexed libs.You can disable pre-dexing by adding the following code to your
app/build.gradle
file:android { // ... dexOptions { preDexLibraries = false } }
Note: Previously, you could set the maximum number of methods per single dex file by adding an additional property underdexOptions
like this:additionalParameters = ["--set-max-idx-number=55000"]
. However, with the new Android compiler D8 and Android studio 3.1.2,–set-max-idx-number
is no longer valid. As a result, if you include this property, you will get an error during app submission. -
Configure your build instructions to ensure that your multidex app is optimized for the Amazon Appstore and the submission process. You have two options:
-
Manually create the
main-dex-list
file. In app/build.gradle file, add the following:afterEvaluate { tasks.matching { it.name.startsWith('dex') }.each { dx -> if (dx.additionalParameters == null) { dx.additionalParameters = [] } dx.additionalParameters += '--multi-dex' dx.additionalParameters += "--main-dex-list=$projectDir/<filename>".toString() } }
This code uses two parameters:
--multi-dex
— enables splitting mechanism in build process.--main-dex-list
— file with list of classes which have to be attached in main dex file.
To ensure that your multidex app will go through submission and be published properly in the Amazon Appstore, use the
--main-dex-list
parameter to put the following in the main.dex
file:- Custom Applications
- Activities
- Services
- Receivers
- Providers
- Instrumentations
- Annotations
-
Ignore the
multi-dex
andmulti-dex-list
parameters if you are using studio 0.9.0+ gradle 0.14.2 and let the build tools automatically limit thedx.additionalParameters
parameter to60,000
. This should work for most applications; however, if you have a very large number of classes in your app, you might find that you will need to manually set your max number to less than 60,000 to have your app pass submission to the Amazon Appstore properly.
-
Keeping the AndroidX library unobfuscated
If you're using AndroidX library for multidexing, keep the AndroidX library unobfuscated in your code by adding this line to your Proguard file:
-keep class androidx/multidex.** { *; }
Additional resources
For assistance in generating the main-dex-list
, see the following::
- CreateManifestKeepList.groovy — this is the source code for how Gradle automatically generates a
main-dex-list
. - A tool that can automatically generate this main-dex-list.
Last updated: Oct 02, 2023