Android 无法执行dex:method ID不在[0,0xffff]:65536中
我以前见过各种版本的dex erros,但这是新版本。清理/重新启动etc不会有帮助。库项目似乎完好无损,依赖关系似乎链接正确Android 无法执行dex:method ID不在[0,0xffff]:65536中,android,dex,Android,Dex,我以前见过各种版本的dex erros,但这是新版本。清理/重新启动etc不会有帮助。库项目似乎完好无损,依赖关系似乎链接正确 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
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
或
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;dr:谷歌的官方解决方案终于出现了
只有一个小提示,您可能需要这样做,以防止在执行索引时内存不足
dexOptions {
javaMaxHeapSize "4g"
}
还有一种巨型模式可以以不太可靠的方式修复此问题:
dexOptions {
jumboMode true
}
更新:如果你的应用程序太胖,并且你的主应用程序中有太多的方法,你可能需要按照重新组织你的应用程序
您的项目太大了。你的方法太多了。每个应用程序只能有65536个方法。请参见此处我共享了一个示例项目,该项目使用自定义的_rules.xml构建脚本和几行代码解决了这个问题 我在自己的项目中使用了它,它在100多万台设备上完美运行(从android-8到最新的android-19)。希望能有帮助
与Proguard合作是解决这一问题的最佳方案。正如aleb在评论中提到的那样。
它会将dex文件的大小减少一半。如果使用Gradle,下面的代码会有所帮助。允许您轻松删除不需要的Google服务(假定您正在使用这些服务),以恢复到65k阈值以下。该职位的所有荣誉: 编辑2014-10-22:关于上面提到的要点,有很多有趣的讨论。太长,读不下去了看看这个: 将此代码粘贴到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
}
}
更新3(2014年11月3日)谷歌终于发布了
更新2(2014年10月31日)
Android多索引Gradle插件v0.14.0。要启用,只需在build.gradle中声明: 如果您的应用程序支持5.0之前的Android(也就是说,如果您的
minSdkVersion
为20或更低),您还必须动态修补应用程序类加载器,以便它能够从辅助索引加载类。幸运的是,有一种方法可以帮你做到这一点。将其添加到应用程序的依赖项:
dependencies {
...
compile 'com.android.support:multidex:1.0.0'
}
您需要尽快调用ClassLoader补丁代码<代码>多索引应用程序类建议了三种方法(选择其中一种方法,一种对您最方便的方法):
1-在AndroidManifest.xml中将MultiDexApplication
类声明为应用程序:
3-从应用程序#attachBaseContext
方法调用MultiDex\install
:
public class MyApplication {
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
....
}
....
}
更新1(2014年10月17日):
正如预期的那样,它在Android支持库的第21版中发布。您可以在/sdk/extras/android/support/multidex/libs文件夹中找到android-support-multidex.jar
多索引支持解决了这个问题。dx 1.8已经允许生成多个dex文件。
Android L将在本机上支持multi-dex,支持库的下一个版本将涵盖API 4的旧版本
安瓦尔·古卢姆在安卓开发者后台播客中提到了这一点。我已经对相关部分进行了(和一般多指标解释)。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/**'
}
}
}
}
}
如前所述,项目和LIB中的方法太多(超过65k) 预防问题:使用Play Services 6.5+和support-v4 24.2减少方法的数量+ 因为Google Play服务经常是其“浪费”方法的主要嫌疑犯之一。Google Play services 6.5版或更高版本,例如,如果您只需要GCM和地图,您可以选择仅使用这些依赖项:
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以来,它被分为以下模块:
支持兼容
,支持核心UTIL
,支持核心ui
,支持媒体兼容
和支持片段
但是请注意,如果您使用supportfragment
,它将依赖于所有其他模块(即,如果您使用android.support.v4.app.fragment
,则没有任何好处)
启用多重索引 由于棒棒糖(又名构建工具21+)非常容易处理。方法是解决每个dex文件65k个方法的问题,为应用程序创建多个dex文件。将以下内容添加到gradle生成文件(): 第二步是准备应用程序类,或者如果不扩展应用程序,请使用Android清单中的
MultiDexApplication
:
或者将其添加到Application.java
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
或使用mutlidex库中提供的应用程序
<?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>
这会将堆设置为4G字节
分析问题的根源 为了分析这些方法的来源,gradle插件可以与gradle提供的依赖树相结合,例如
.\gradlew app:dependencies
面对同样的问题,通过在“依赖项”部分编辑my 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
}
从Libs文件夹中删除一些jar文件并复制到其他文件夹,然后转到_projectproperties>Select Java Build Path,选择Libraries,选择Add External jar,选择删除的jar到您的项目中,单击save,这将添加到引用库下而不是Libs文件夹下。现在清理并运行您的项目。您不需要为MultDex添加任何代码。这对我很有效。您可以使用Android Studio分析问题(dex文件引用): 构建->分析APK 在结果面板上,单击classes.dex文件 你会看到:
我今天也面临着同样的问题,到底是什么在起作用 对于ANDROID STUDIO。。。启用即时R
.\gradlew app:dependencies
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'
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
multiDexEnabled true
}