无法执行dex:方法ID不在[0,0xffff]: 65536

我以前见过不同版本的dex错误,但这一个是新的。清洁/重新启动等不会有帮助。库项目似乎完好无损,依赖项似乎正确链接。

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

< em >或< / em >

Cannot merge new index 65950 into a non-jumbo instruction

< em >或< / em >

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

博士tl;:谷歌的官方解决方案终于来了!

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

145745 次浏览

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

我已经分享了一个使用custom_rules.xml构建脚本和几行代码解决这个问题的示例项目。

我在自己的项目中使用了它,它在100多万设备上运行完美无缺(从android-8到最新的android-19)。希望能有所帮助。

https://github.com/mmin18/Dex65536 < a href = " https://github.com/mmin18/Dex65536 " > < / >

完美的解决方案是与Proguard合作。正如aleb在评论中提到的。 它会将dex文件的大小减半

如果你使用Gradle,下面的代码会有所帮助。允许您轻松删除不需要的谷歌服务(假设您正在使用它们),以恢复到低于65k阈值。所有的功劳都归于这篇文章:https://gist.github.com/dmarcato/d7c91b94214acd936e42

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

将此代码粘贴到构建的底部。Gradle文件,调整你不需要的谷歌服务列表:

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
}
}
< p > 更新三(11/3/2014) < br > 谷歌终于释放了官方的描述.

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

android {
defaultConfig {
...
multiDexEnabled  true
}
}

如果你的应用程序支持5.0之前的Android(也就是说,如果你的minSdkVersion是20或更低),你还必须动态地修补应用程序类加载器,这样它将能够从辅助索引加载类。幸运的是,有一个图书馆为你做这件事。将它添加到应用程序的依赖项中:

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

您需要尽快调用ClassLoader补丁代码。MultiDexApplication类的文档提出了三种方法(选择其中之一,对你来说最方便):

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

从你的Application#attachBaseContext方法调用MultiDex#install:

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

< p > 更新1 (10/17/2014): < br > 正如预期的那样,multidex支持在Android支持库的第21版中发布。你可以在/sdk/extras/android/support/multidex/library/libs文件夹中找到android-support-multidex.jar

多索引支持解决这个问题。Dx 1.8已经允许生成几个dex文件 Android L将原生支持多索引,支持库的下一个版本将覆盖API 4的旧版本。< / p >

这是由Anwar Ghuloum在 Android Developers Backstage播客中陈述的。我有相关部分的发布文字记录(和一般的多索引解释)。

Gradle + proguard解决方案:

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

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

预防问题:使用Play Services 6.5+和support-v4 24.2+减少方法的数量

因为通常谷歌播放服务是浪费20 k +方法方法的主要嫌疑人之一。例如,如果你只需要GCM和map,你可以选择只使用这些依赖项:

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

子库的完整列表及其职责可以在谷歌官方文档中找到

更新:从支持库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

因为棒棒糖(又名构建工具21+)非常容易处理。方法是解决每个dex文件有65k个方法的问题,为你的应用程序创建多个dex文件。将以下内容添加到你的gradle构建文件(这是来自谷歌官方文档中关于超过65000个方法的应用程序):

android {
compileSdkVersion 21
buildToolsVersion "21.1.0"


defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}


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

第二步是准备你的应用程序类,或者如果你不扩展应用程序,在你的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异常,你可以用

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

这将把堆设置为4gb。

关于dex堆内存问题的更多细节


分析问题的根源

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

.\gradlew app:dependencies

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

面对同样的问题,通过编辑我的构建解决了它。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'

尝试在构建中添加以下代码。Gradle,它对我很管用

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
multiDexEnabled true
}

从Libs文件夹中删除一些jar文件并复制到其他文件夹,然后进入_Project Properties >,选择Java构建路径,选择Libraries,选择添加外部jar,选择已删除的jar到您的项目,单击保存,这将被添加到引用库,而不是Libs文件夹。现在清理并运行项目。你不需要添加任何代码为多dex。这对我来说很有效。

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

Build ->分析APK ..

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

你会看到:

enter image description here

我今天也遇到了同样的问题下面是有效的方法

为ANDROID工作室…启用立即运行

In File->Preferences->Build, Execution, Deployment->Instant Run-> Check Enable Instant Run for热插拔…

希望能有所帮助