无法执行dex:方法ID不在:65536

以前我见过各种版本的dex erros,但是这个是新的。 干净/重新启动等不会帮助。 库项目似乎完好无损,依赖关系似乎正确链接。

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 

要么

 Cannot merge new index 65950 into a non-jumbo instruction 

要么

 java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 

tl;博士 :Google的官方解决scheme终于来了!

http://developer.android.com/tools/building/multidex.html

只有一个小提示,你可能需要这样做,以防止分配时出现内存不足。

 dexOptions { javaMaxHeapSize "4g" } 

还有一个巨型模式,可以解决这个不太可靠的方式:

 dexOptions { jumboMode true } 

更新:如果您的应用程序很胖,并且您的主应用程序中有太多的方法,则可能需要按照每个应用程序重新组织您的应用程序

http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html

更新3(11/3/2014)
Google终于发布了官方说明 。


更新2(10/31/2014)
Android版Gradle插件v0.14.0 增加了对multi-dex的支持 。 要启用,你只需要在build.gradle中声明它:

 android { defaultConfig { ... multiDexEnabled true } } 

如果您的应用程序支持5.0之前的Android(也就是说,如果您的minSdkVersion是20或更低版本),则还必须dynamic地修补应用程序ClassLoader ,以便能够从二级区域加载类。 幸运的是,有一个图书馆可以帮你。 将它添加到您的应用程序的依赖关系:

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

您需要尽快调用ClassLoader补丁代码。 MultiDexApplication类的文档提供了三种方法来做到这一点(select其中的一个,这对你来说最为方便):

1 – 在您的AndroidManifest.xml中声明MultiDexApplication类作为应用程序:

 <?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 – 让您的Application类扩展MultiDexApplication类:

 public class MyApplication extends MultiDexApplication { .. } 

3 – 从您的Application#attachBaseContext方法调用MultiDex#install

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

更新1(10/17/2014):
正如预期的那样 ,Android支持库修订版21中提供了multidex支持 。 你可以在/ sdk / extras / android / support / multidex / library / libs文件夹中findandroid-support-multidex.jar。


Multi-dex支持解决了这个问题。 DX 1.8已经允许生成几个DEX文件。
Android L将本机支持multi-dex,支持库的下一个版本将覆盖API 4的旧版本。

这是由安华Ghuloum在这个 Android开发人员后台播客插曲。 我已经发布了相关部分的成绩单 (和一般多指标解释)。

如前所述,您的项目和库中有太多的方法(超过65k)。

预防问题:减less播放服务6.5+和支持-v4 24.2+的方法数量

由于Google Play服务经常以其20k +方法 “浪费”方法的主要嫌疑犯之一。 Google Play服务版本6.5或更高版本,您可以使用许多小型客户端库将Google Play服务包含在您的应用程序中。 例如,如果您只需要GCM和地图,则只能select使用这些依赖关系:

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

完整的子库列表和它的职责可以在官方的谷歌文档中find 。

更新 :自Support Library v4 v24.2.0以来,它被分成以下模块:

support-compatsupport-core-utilssupport-core-uisupport-media-compatsupport-fragment

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

不过要注意的是,如果你使用support-fragment ,它将对所有其他模块有依赖关系(例如,如果你使用android.support.v4.app.Fragment没有任何好处)

请参阅support-v4 lib官方发行说明


启用MultiDexing

由于棒棒糖(aka build tools 21+),它很容易处理。 该方法是解决每个dex文件问题的65k方法,为您的应用程序创build多个dex文件。 将以下内容添加到您的Gradle构build文件( 这是从超过65k方法的应用程序的官方谷歌文档 ):

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

第二步是准备您的Application类,或者如果您不扩展Application,请使用Android Manifest中的MultiDexApplication

或者将其添加到您的Application.java

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

或者使用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> 

使用MultiDex防止OutOfMemory

作为进一步的提示,如果你在构build阶段遇到OutOfMemoryexception,你可以放大堆

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

这将堆设置为4千兆字节。

有关dex堆内存问题的更多详细信息,请参阅此问题。


分析问题的根源

为了分析方法的来源,gradle插件https://github.com/KeepSafe/dexcount-gradle-plugin可以帮助结合gradle提供的依赖树和eg

 .\gradlew app:dependencies 

看到这个答案和问题的Android的方法计数的更多信息

你的项目太大了。 你有太多的方法。 每个应用程序只能有65536个方法。 请参阅https://code.google.com/p/android/issues/detail?id=7147#c6

下面的代码可以帮助你,如果你使用Gradle。 允许您轻松删除不需要的Google服务(假设您正在使用它们),以便低于65k的阈值。 所有信贷到这个职位: https : //gist.github.com/dmarcato/d7c91b94214acd936e42

编辑2014-10-22 :上面提到的要点已经有很多有趣的讨论。 TLDR? 看看这个: https : //gist.github.com/Takhion/10a37046b9e6d259bb31

将此代码粘贴到build.gradle文件的底部,然后调整您不需要的Google服务列表:

 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 } } 

我已经使用custom_rules.xml构build脚本和几行代码共享了解决此问题的示例项目。

我用它在我自己的项目上,它运行在1M +设备上(从android-8到最新的android-19)完美无瑕。 希望它有帮助。

https://github.com/mmin18/Dex65536

面对同样的问题,并通过在依赖部分编辑我的build.gradle文件解决它,删除:

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

取而代之的是:

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

尝试在build.gradle中添加下面的代码,它为我工作 –

 compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { multiDexEnabled true } 

完美的解决scheme是与Proguard合作。 正如评论中提到的那样。 它会减less一半的dex文件的大小。

gradle + proguard解决scheme:

 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/**' } } } } } 

从Libs文件夹中删除一些jar文件并复制到其他文件夹,然后转到_Project属性>selectJava Build Path,selectLibraries,selectAdd External Jar,selectRemoved jar到你的项目中,点击save,将被添加到Referenced库而不是Libs文件夹。 现在清理并运行你的项目。 您不需要为MultDex添加任何代码。 它只是为我工作。

您可以使用Android Studio分析问题(dex文件引用):

构build – >分析APK ..

在结果面板上点击classes.dex文件

你会看到:

在这里输入图像描述

我今天面临着同样的问题

对于ANDROID STUDIO …启用即时运行

在文件 – >首选项 – >生成,执行,部署 – >即时运行 – >检查启用即时运行热插拔…

希望它有帮助