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

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 your Review Status tab 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 Building Apps with Over 65K 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 Building Apps with Over 65K 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 new 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:

  1. Make sure you have updated your Android Build Tools to the latest version. You will need at least version 21.1.x or later.
  2. Add the android-support-multidex.jar library into your project. You can find it in \android-sdk\extras\android\support\multidex\library\libs.
  3. Add multiDexEnabled true and a Multidex dependency to your buildConfig in the build.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'
    } 
    
  4. Either override the android.app.Application class, or declare the MultiDexApplication 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>
    
  5. 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
        }
    }
    
  6. Configure your build instructions to ensure that your multidex app is optimized for the Amazon Appstore and the submission process. You have two options:

    1. 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
    2. Ignore the multi-dex and multi-dex-list parameters if you are using studio 0.9.0+ gradle 0.14.2 and let the build tools automatically limit the dx.additionalParameters parameter to 60,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.

Additional Resources

For assistance in generating the main-dex-list, see the following::