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

Edi*_*son 341 android dex

我以前见过各种版本的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
Run Code Online (Sandbox Code Playgroud)

要么

Cannot merge new index 65950 into a non-jumbo instruction
Run Code Online (Sandbox Code Playgroud)

要么

java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
Run Code Online (Sandbox Code Playgroud)

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

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

只有一个小提示,你可能需要这样做以防止在执行dex-ing时内存不足.

dexOptions {
        javaMaxHeapSize "4g"
}
Run Code Online (Sandbox Code Playgroud)

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

dexOptions {
        jumboMode true
}
Run Code Online (Sandbox Code Playgroud)

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

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

Ale*_*pov 376

更新3(11/3/2014)
谷歌终于发布了官方说明.


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

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序支持5.0之前的Android(即,如果您的minSdkVersion是20或更低),您还必须动态修补应用程序ClassLoader,因此它将能够从辅助dexes加载类.幸运的是,有一个可以帮到你.将其添加到您应用的依赖项:

dependencies {
  ...
  compile 'com.android.support:multidex:1.0.0'
} 
Run Code Online (Sandbox Code Playgroud)

您需要尽快调用ClassLoader补丁代码.MultiDexApplicationclass的文档提供了三种方法(选择其中一种方法,一种对您来说最方便):

1 - 将MultiDexApplication类声明为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>
Run Code Online (Sandbox Code Playgroud)

2 - 让您的Application类扩展MultiDexApplication类:

public class MyApplication extends MultiDexApplication { .. }
Run Code Online (Sandbox Code Playgroud)

3 - MultiDex#install从您的Application#attachBaseContext方法致电:

public class MyApplication {
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        ....
    }
    ....
}
Run Code Online (Sandbox Code Playgroud)

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


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

Anwar Ghuloum 在 Android开发者Backstage播客节目中阐述了一点.我发布了相关部分的成绩单(以及一般的多指令解释).

  • @MuhammadBabar有Eclipse用户的Android工作室. (52认同)
  • eclipse用户的任何东西? (39认同)
  • 博客文章是一个保护者!:d (2认同)
  • @MohammedAli当然,如果可以,请避免使用它.但是,如果你真的*在你的应用程序中有太多的方法,你应该怎么做,你已经尝试过所提到的所有技巧?关于构建时间 - 有解决方案,至少对于开发构建 - 请参阅我的答案:http://stackoverflow.com/a/30799491/1233652 (2认同)
  • 在Qt for Android上,我在运行时为我的应用程序在将Facebook + Twitter的SDK集成在一起时遇到了问题,即使在启用了multidex支持之后(这一个错误特别让我做了噩梦:`java.lang.ClassNotFoundException:没找到类) org.qtproject.qt5.android.QtActivityDelegate"on path:DexPathList [[],nativeLibraryDirectories = [/ vendor/lib,/ system/lib]]`).事实证明,我的错误是我没有在5.0之前应用Android支持的额外步骤.话虽如此,选项#3解决了它,我没有更多的'ClassNotFoundException`问题.谢谢,@ Alex Lipov! (2认同)

pat*_*ckf 77

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

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

由于Google Play服务通常是使用其20k +方法 "浪费"方法的主要嫌疑人之一.Google Play服务6.5或更高版本,您可以使用许多较小的客户端库在您的应用程序中包含Google Play服务.例如,如果您只需要GCM和地图,则可以选择仅使用这些依赖项:

dependencies {
    compile 'com.google.android.gms:play-services-base:6.5.+'
    compile 'com.google.android.gms:play-services-maps:6.5.+'
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

dependencies {
    compile 'com.android.support:support-fragment:24.2.+'
}
Run Code Online (Sandbox Code Playgroud)

但请注意,如果您使用support-fragment,它将依赖于所有其他模块(即,如果您使用android.support.v4.app.Fragment,则没有任何好处)

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


启用MultiDexing

由于Lollipop(又名构建工具21+),它很容易处理.方法是解决每个dex文件问题的65k方法,为您的应用程序创建多个dex文件.将以下内容添加到您的gradle构建文件中(这是从官方google doc上获取的超过65k方法的应用程序):

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

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

dependencies {
  compile 'com.android.support:multidex:1.0.1'
}
Run Code Online (Sandbox Code Playgroud)

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

将其添加到Application.java中

@Override
  protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
  }
Run Code Online (Sandbox Code Playgroud)

使用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>
Run Code Online (Sandbox Code Playgroud)

使用MultiDex防止OutOfMemory

作为进一步的提示,如果OutOfMemory在构建阶段遇到异常,可以使用扩展堆

android {
    ...
    dexOptions {
        javaMaxHeapSize "4g"
    }
}
Run Code Online (Sandbox Code Playgroud)

这会将堆设置为4千兆字节.

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


分析问题的根源

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

.\gradlew app:dependencies
Run Code Online (Sandbox Code Playgroud)

有关android中方法计数的更多信息,请参阅此答案和问题

  • Play Services 6.5+解决方案做到了这一点,谢谢! (2认同)

小智 57

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

  • 这对于android来说真是令人尴尬的错误!无论如何,在我的情况下,我删除了在libs中的Jar,并且没有使用,并且应用程序已编译 (7认同)
  • 更具体地说,每个Dalvik可执行文件(dex)文件只能有65,536个方法.并且应用程序(APK)可以有多个dex文件,例如自定义加载. (5认同)

mcm*_*mcm 12

如果您使用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
    }
}
Run Code Online (Sandbox Code Playgroud)


mmi*_*min 6

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

我在我自己的项目中使用它,它在1M +设备上运行完美(从android-8到最新的android-19).希望能帮助到你.

https://github.com/mmin18/Dex65536

  • 当我将项目导入Eclipse并运行时会出错."无法执行dex:方法ID不在[0,0xffff]:65536"中.你能解释一下这个项目的用法吗? (2认同)

小智 6

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

compile 'com.google.android.gms:play-services:7.8.0'
Run Code Online (Sandbox Code Playgroud)

并替换为:

compile 'com.google.android.gms:play-services-location:7.8.0'
compile 'com.google.android.gms:play-services-analytics:7.8.0' 
Run Code Online (Sandbox Code Playgroud)


Sun*_*ita 5

尝试在build.gradle中添加以下代码,它对我有用 -

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

142304 次

最近记录:

7 年,1 月 前