65k Method Limit in DEX

I became extremely frustrated when my Android project refused to build after integrating the Google Drive API. I discovered that my project exceeded the number of methods allowed in classes.dex. The proposed solution by Google— embed a secondary DEX file in assets and use DexClassLoader and reflection at runtime—seemed absurd. However, I did manage to successfully package the Google Drive API into a separate DEX, load it via DexClassLoader and call the API via reflection. This worked in a production app with tens-of-thousands of daily active users. It was the only solution at the time. After many hours of complex reflection I felt like throwing my computer out the window!

I was the first developer to post about the 65k method limit on StackOverflow.com. After my post, Facebook shared a solution to a similar issues and their Dalvik patch solution. In 2014 Google finally addressed the issue by introducing multidex.


Question

I have a rather large Android app that relies on many library projects. The Android compiler has a limitation of 65536 methods per .dex file and I am surpassing that number.

There are basically two paths you can choose (at least that I know of) when you hit the method limit.

1) Shrink your code

2) Build multiple dex files (see this blog post)

I looked into both and tried to find out what was causing my method count to go so high. The Google Drive API takes the biggest chunk with the Guava dependency at over 12,000. Total libs for Drive API v2 reach over 23,000!

My question I guess is, what do you think I should do? Should I remove Google Drive integration as a feature of my app? Is there a way to shrink the API down (yes, I use proguard)? Should I go the multiple dex route (which looks rather painful, especially dealing with third party APIs)?

Answer

It looks like Google has finally implementing a workaround/fix for surpassing the 65K method limit of dex files.

About the 65K Reference Limit

Android application (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536, including Android framework methods, library methods, and methods in your own code. Getting past this limit requires that you configure your app build process to generate more than one DEX file, known as a multidex configuration.

Multidex support prior to Android 5.0

Versions of the platform prior to Android 5.0 use the Dalvik runtime for executing app code. By default, Dalvik limits apps to a single classes.dex bytecode file per APK. In order to get around this limitation, you can use the multidex support library, which becomes part of the primary DEX file of your app and then manages access to the additional DEX files and the code they contain.

Multidex support for Android 5.0 and higher

Android 5.0 and higher uses a runtime called ART which natively supports loading multiple dex files from application APK files. ART performs pre-compilation at application install time which scans for classes(..N).dex files and compiles them into a single .oat file for execution by the Android device. For more information on the Android 5.0 runtime, see Introducing ART.

See: Building Apps with Over 65K Methods


Multidex Support Library

This library provides support for building apps with multiple Dalvik Executable (DEX) files. Apps that reference more than 65536 methods are required to use multidex configurations. For more information about using multidex, see Building Apps with Over 65K Methods.

This library is located in the /extras/android/support/multidex/ directory after you download the Android Support Libraries. The library does not contain user interface resources. To include it in your application project, follow the instructions for [Adding libraries without resources][5].

The Gradle build script dependency identifier for this library is as follows:

com.android.support:multidex:1.0.+ This dependency notation specifies the release version 1.0.0 or higher.


You should still avoid hitting the 65K method limit by actively using proguard and reviewing your dependencies.