Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

  • Dexdex link
  • Dexter link
  • Secondary dex gradle link

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

like image 699
Ivan Morgillo Avatar asked May 12 '14 16:05

Ivan Morgillo


3 Answers

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).

like image 65
sschuberth Avatar answered Sep 19 '22 02:09

sschuberth


In case gms was your issue and you are using gradle

Starting from gms version 6.5 you can choose individual API libraries

for example to include only the Maps API :

compile 'com.google.android.gms:play-services-maps:6.5.87'

and here is the complete list :

      com.google.android.gms:play-services-base:6.5.87
      com.google.android.gms:play-services-ads:6.5.87
      com.google.android.gms:play-services-appindexing:6.5.87
      com.google.android.gms:play-services-maps:6.5.87
      com.google.android.gms:play-services-location:6.5.87
      com.google.android.gms:play-services-fitness:6.5.87
      com.google.android.gms:play-services-panorama:6.5.87
      com.google.android.gms:play-services-drive:6.5.87
      com.google.android.gms:play-services-games:6.5.87
      com.google.android.gms:play-services-wallet:6.5.87
      com.google.android.gms:play-services-identity:6.5.87
      com.google.android.gms:play-services-cast:6.5.87
      com.google.android.gms:play-services-plus:6.5.87
      com.google.android.gms:play-services-appstate:6.5.87
      com.google.android.gms:play-services-wearable:6.5.87
      com.google.android.gms:play-services-all-wear:6.5.87
like image 26
idanakav Avatar answered Sep 18 '22 02:09

idanakav


An example project partitioning and loading different dex files can be found here:

https://code.google.com/p/android-custom-class-loading-sample/

EDIT: For Gradle you already have an answer

Custom Class Loading in Dalvik with Gradle (Android New Build System)

like image 42
kikoso Avatar answered Sep 18 '22 02:09

kikoso