Using Gradle to split external libraries in separated dex files to solve Android Dalvik 64k methods limit

Ivan Morgillo picture Ivan Morgillo · May 12, 2014 · Viewed 12.6k times · Source

Is there a proper/easy way to solve the 64k methods limit using Gradle?

I mean some custom Gradle task to use pre-dexed jars to create separated dex files, instead of a single classes.dex.

Thank you

Ivan

Current status

Currently, I'm struggling with GMS: it brings in 20k methods to use Analytics. I use Proguard to strip down what's not need, but still... 72k methods and counting...

I can split classes.dex in two file using dx parameter --multi-dex. I achieved it manually editing

sdk/build-tools/android-4.4W/dx

and editing last line like this:

exec java $javaOpts -jar "$jarpath" --multi-dex "$@"

My APK file now contains __classes.dex__ and __classes2.dex__.

I'm trying to dynamically load the second file with a few methods:

Unfortunately still no luck. I really hope some Google/Facebook/Square guru can provide a proper solution.

Answer

sschuberth picture sschuberth · Sep 22, 2014

Update for Android Gradle plugin 2.2.0: It is not possible to access the dex task anymore, but in exchange additionalParameters was introduced as part of dexOptions. Use it like

android {
  dexOptions {
    additionalParameters += '--minimal-main-dex'
    // additionalParameters += '--main-dex-list=$projectDir/<filename>'.toString()
    // additionalParameters += '--set-max-idx-number=55000'
  }
}

Update for Android Gradle plugin 0.14.0: There is now direct multi-dex support via the new multiDexEnabled true directive (requires build-tools 21.1.0, support repository revision 8, and Android Studio 0.9).

Original answer: Ever since Gradle Android plugin 0.9.0 you actually can pass the --multi-dex to dx by adding this to you app's build.gradle file:

afterEvaluate {
    tasks.matching {
        it.name.startsWith('dex')
    }.each { dx ->
        if (dx.additionalParameters == null) {
            dx.additionalParameters = ['--multi-dex']
        } else {
            dx.additionalParameters += '--multi-dex'
        }

        // Add more additional parameters like this:
        dx.additionalParameters += '--main-dex-list=class-list.txt'
        dx.additionalParameters += '--minimal-main-dex'
    }
}

So far for the creating he multiple dex files. To actually use the multiple dex files, take a look at https://github.com/casidiablo/multidex (which is a fork of Google's upcoming MultiDex support library).