347

I have seen various versions of the dex erros before, but this one is new. clean/restart etc won't help. Library projects seems intact and dependency seems to be linked correctly.

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 

or

Cannot merge new index 65950 into a non-jumbo instruction 

or

java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 
6
  • 1
    Do you use api which is not aviable on your currient device? Commented Mar 4, 2013 at 19:47
  • It's there, because another project build fine targeting the same API version. Commented Mar 4, 2013 at 19:50
  • So you use at some point API which is not available? Do you check with a line like if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) that you don't call this function if it is not available? Commented Mar 4, 2013 at 19:57
  • Yea, I do. The project built fine before. Also, that should be a runtime error even if I missed the line. Commented Mar 4, 2013 at 20:05
  • It's probably one of the dependencies is messed up. (doing a mix of maven+project lib right now) Commented Mar 4, 2013 at 20:05

12 Answers 12

380

Update 3 (11/3/2014)
Google finally released official description.


Update 2 (10/31/2014)
Gradle plugin v0.14.0 for Android adds support for multi-dex. To enable, you just have to declare it in build.gradle:

android { defaultConfig { ... multiDexEnabled true } } 

If your application supports Android prior to 5.0 (that is, if your minSdkVersion is 20 or below) you also have to dynamically patch the application ClassLoader, so it will be able to load classes from secondary dexes. Fortunately, there's a library that does that for you. Add it to your app's dependencies:

dependencies { ... compile 'com.android.support:multidex:1.0.0' } 

You need to call the ClassLoader patch code as soon as possible. MultiDexApplication class's documentation suggests three ways to do that (pick one of them, one that's most convenient for you):

1 - Declare MultiDexApplication class as the application in your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.multidex.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application> </manifest> 

2 - Have your Application class extend MultiDexApplication class:

public class MyApplication extends MultiDexApplication { .. } 

3 - Call MultiDex#install from your Application#attachBaseContext method:

public class MyApplication { protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); .... } .... } 

Update 1 (10/17/2014):
As anticipated, multidex support is shipped in revision 21 of Android Support Library. You can find the android-support-multidex.jar in /sdk/extras/android/support/multidex/library/libs folder.


Multi-dex support solves this problem. dx 1.8 already allows generating several dex files.
Android L will support multi-dex natively, and next revision of support library is going to cover older releases back to API 4.

It was stated in this Android Developers Backstage podcast episode by Anwar Ghuloum. I've posted a transcript (and general multi-dex explanation) of the relevant part.

Sign up to request clarification or add additional context in comments.

27 Comments

Marking this as the answer as of time of this comment.
Anything for eclipse users?
@MuhammadBabar There is Android studio for Eclipse users.
@MohammedAli Sure, avoid using it if you can. But what should you do if you really have too many methods in your app, and you already tried all the tricks like the one that you mentioned? Regarding the build time - there's solution for this, at least for development builds - see my answer here: stackoverflow.com/a/30799491/1233652
On Qt for Android, I was having issues at runtime for my app when integrating Facebook+Twitter's SDKs together, even after enabling multidex support (this one error in particular gave me nightmares: java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt5.android.QtActivityDelegate" on path: DexPathList[[],nativeLibraryDirectories=[/vendor/lib, /system/lib]]). It turned out that my mistake was that I wasn't applying the additional steps for Android support prior to 5.0. With that said, option #3 solved it, and I had no more ClassNotFoundException issues. Thanks, @Alex Lipov!
|
78

As already stated, you have too many methods (more than 65k) in your project and libaries.

Prevent the Problem: Reduce the number of methods with Play Services 6.5+ and support-v4 24.2+

Since often the Google Play Services is one of the main suspects in "wasting" methods with its 20k+ methods. Google Play Services version 6.5 or later, it is possible for you to include Google Play Services in your application using a number of smaller client libraries. For example, if you only need GCM and maps you can choose to use these dependencies only:

dependencies { compile 'com.google.android.gms:play-services-base:6.5.+' compile 'com.google.android.gms:play-services-maps:6.5.+' } 

The full list of sub libraries and its responsibilities can be found in the official google doc.

Update: Since Support Library v4 v24.2.0 it was split up into the following modules:

support-compat, support-core-utils, support-core-ui, support-media-compat and support-fragment

dependencies { compile 'com.android.support:support-fragment:24.2.+' } 

Do note however, if you use support-fragment, it will have dependencies to all the other modules (i.e. if you use android.support.v4.app.Fragment there is no benefit)

See here the official release notes for support-v4 lib


Enable MultiDexing

Since Lollipop (aka build tools 21+) it is very easy to handle. The approach is to work around the 65k methods per DEX file problem to create multiple DEX files for your app. Add the following to your Gradle build file (this is taken from the official google doc on applications with more than 65k methods):

android { compileSdkVersion 21 buildToolsVersion "21.1.0" defaultConfig { ... // Enabling multidex support. multiDexEnabled true } ... } dependencies { compile 'com.android.support:multidex:1.0.1' } 

The second step is to either prepare your Application class or if you don't extend Application use the MultiDexApplication in your Android Manifest:

Either add this to your Application.java

@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } 

or use the provided application from the mutlidex lib

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.myapplication"> <application ... android:name="android.support.multidex.MultiDexApplication"> ... </application> </manifest> 

Prevent OutOfMemory with MultiDex

As further tip, if you run into OutOfMemory exceptions during the build phase you could enlarge the heap with

android { ... dexOptions { javaMaxHeapSize "4g" } } 

which would set the heap to 4 gigabytes.

See this question for more detail on the DEX heap memory issue.


Analyze the source of the Problem

To analyze the source of the methods the Gradle plugin https://github.com/KeepSafe/dexcount-gradle-plugin can help in combination with the dependency tree provided by Gradle with e.g.

.\gradlew app:dependencies 

See this answer and question for more information on method count in android

4 Comments

I've used Play Services 6.5+ solution and it worked perfectly. Incredible useful tip. Thanks so much!
I'd upvote more if I could - cutting out all the other Play Services stuff that we weren't using fixed this issue, without having to resort to multi-dex, which has negative performance implications when building.
Than you so much with tears in my eyes. You saved me
I used client library for GCM, because I am using only gcm service from play service, now it fixed my problem with this. Thanks! to save my time.
56

Your project is too large. You have too many methods. There can only be 65536 methods per application. see here https://code.google.com/p/android/issues/detail?id=7147#c6

5 Comments

I see. I do have lots of dependencies for this project. It builds fine before I moved to use maven though, maybe maven added unnecessary dependencies. Will double check.
To be more specific, there can only be 65,536 methods per Dalvik executable (dex) file. And an application (APK) can have more than one dex file with such things as custom loading.
It's really embarrassing bug for android! Anyway, In me case I removed Jar that was in the libs and wasn't in use, and the app compiled
Time to clean up my project :/
A quick fix would be to use Proguard also with the debug builds
12

The below code helps, if you use Gradle. Allows you to easily remove unneeded Google services (presuming you're using them) to get back below the 65k threshold. All credit to this post: https://gist.github.com/dmarcato/d7c91b94214acd936e42

Edit 2014-10-22: There's been a lot of interesting discussion on the gist referenced above. TLDR? look at this one: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Paste this code at the bottom of your build.gradle file and adjust the list of google services you do not need:

def toCamelCase(String string) { String result = "" string.findAll("[^\\W]+") { String word -> result += word.capitalize() } return result } afterEvaluate { project -> Configuration runtimeConfiguration = project.configurations.getByName('compile') ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult // Forces resolve of configuration ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library" File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") { inputs.files new File(playServiceRootFolder, "classes.jar") outputs.dir playServiceRootFolder description 'Strip useless packages from Google Play Services library to avoid reaching dex limit' doLast { copy { from(file(new File(playServiceRootFolder, "classes.jar"))) into(file(playServiceRootFolder)) rename { fileName -> fileName = "classes_orig.jar" } } tasks.create(name: "stripPlayServices" + module.version, type: Jar) { destinationDir = playServiceRootFolder archiveName = "classes.jar" from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) { exclude "com/google/ads/**" exclude "com/google/android/gms/analytics/**" exclude "com/google/android/gms/games/**" exclude "com/google/android/gms/plus/**" exclude "com/google/android/gms/drive/**" exclude "com/google/android/gms/ads/**" } }.execute() delete file(new File(playServiceRootFolder, "classes_orig.jar")) } } project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task -> task.dependsOn stripPlayServices } } 

6 Comments

Love it! def needed as companies like Google keep inflating the packages.
Nice - this did the job spot on. No hasswle and no worry!
Note: this deleted google play services jars in my Android SDK in Android Studio! A bad idea since it's not easy to revert back to original jars. The author should modify the script to change the jars in the build directory.
@inder: I didn't have that problem. However, I did have to do a clean each time I monkeyed with the excludes (we use analytics).
how to exclude this from release builds?
|
6

Faced the same problem and solved it by editing my build.gradle file on the dependencies section, removing:

compile 'com.google.android.gms:play-services:7.8.0' 

And replacing it with:

compile 'com.google.android.gms:play-services-location:7.8.0' compile 'com.google.android.gms:play-services-analytics:7.8.0' 

1 Comment

Perfect! I just use the Google Drive API and this works.
5

I've shared a sample project which solve this problem using custom_rules.xml build script and a few lines of code.

I used it on my own project and it is runs flawless on 1M+ devices (from android-8 to the latest android-19). Hope it helps.

https://github.com/mmin18/Dex65536

2 Comments

Thanks for the scripts. you should watch out for ART. Device may convert only your default dex and not the secondary ones. Proguard solutions should be preferred.
When i import the projects into the Eclipse and run it gives error. "Unable to execute dex: method ID not in [0, 0xffff]: 65536". Can you explaing the usage of the project
5

Try adding below code in build.gradle, it worked for me -

compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { multiDexEnabled true } 

Comments

2

The perfect solution for this would be to work with Proguard. as aleb mentioned in the comment. It will decrease the size of the dex file by half.

1 Comment

Agreed, with an increasingly large google play services jar especially *(18k methods by itself)
2

You can analyse problem (dex file references) using Android Studio:

Build -> Analyse APK ..

On the result panel click on classes.dex file

And you'll see:

enter image description here

Comments

0

gradle + proguard solution:

afterEvaluate { tasks.each { if (it.name.startsWith('proguard')) { it.getInJarFilters().each { filter -> if (filter && filter['filter']) { filter['filter'] = filter['filter'] + ',!.readme' + ',!META-INF/LICENSE' + ',!META-INF/LICENSE.txt' + ',!META-INF/NOTICE' + ',!META-INF/NOTICE.txt' + ',!com/google/android/gms/ads/**' + ',!com/google/android/gms/cast/**' + ',!com/google/android/gms/games/**' + ',!com/google/android/gms/drive/**' + ',!com/google/android/gms/wallet/**' + ',!com/google/android/gms/wearable/**' + ',!com/google/android/gms/plus/**' + ',!com/google/android/gms/topmanager/**' } } } } } 

Comments

0

Remove some jar file from Libs folder and copy to some other folder, And Go to _Project Properties > Select Java Build Path, Select Libraries, Select Add External Jar, Select the Removed jar to your project, Click save, this will be added under Referenced Library instead of Libs folder. Now clean and Run your project. You dont need to add Any code for MultDex. Its simply worked for me.

Comments

0

I was facing the same issue today what worked for is below down

For ANDROID STUDIO... Enable Instant Run

In File->Preferences->Build, Execution, Deployment->Instant Run-> Check Enable Instant run for hot swap...

Hope it helps

1 Comment

This worked for me - I simply disabled Enable Run, clicked Apply, reenabled it, and it worked again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.