.dex 文件中的方法引用数超过 64K

Posted

技术标签:

【中文标题】.dex 文件中的方法引用数超过 64K【英文标题】:The number of method references in a .dex file exceed 64K 【发布时间】:2016-09-22 15:44:56 【问题描述】:

在我的项目中包含播放服务和 firebase 库后,目前正在开发我的 android 应用程序,但出现此错误并且无法运行我的代码

:app:prePackageMarkerForDebug :app:transformClassesWithDexForDebug 要在进程中运行 dex,Gradle 守护进程需要更大的堆。 它目前大约有 910 MB。 要加快构建速度,请将 Gradle 守护程序的最大堆大小增加到 2048 MB 以上。 为此,请在项目 gradle.properties 中设置 org.gradle.jvmargs=-Xmx2048M。 欲了解更多信息,请参阅https://docs.gradle.org/current/userguide/build_environment.html 错误:.dex 文件中的方法引用数不能超过 64K。 在https://developer.android.com/tools/building/multidex.html 了解如何解决此问题 :app:transformClassesWithDexForDebug 失败 错误:任务“:app:transformClassesWithDexForDebug”执行失败。 com.android.build.api.transform.TransformException:com.android.ide.common.process.ProcessException:java.util.concurrent.ExecutionException:com.android.ide.common.process.ProcessException:org.gradle.process。 internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java'' 以非零退出值 2 结束

我的 build.gradle 文件在这里:

apply plugin: 'com.android.application'

android 
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig 
    applicationId "xyz.in.network"
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"

buildTypes 
    release 
        shrinkResources true
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        multiDexEnabled true
    



dependencies 
   compile fileTree(dir: 'libs', include: ['*.jar'])
   testCompile 'junit:junit:4.12'
   compile project(':libs:ViewPagerIndicator')
   compile 'com.google.android.gms:play-services:9.0.0'
   compile 'com.android.support:appcompat-v7:23.4.0'
   compile 'com.android.support:design:23.4.0'
   compile 'com.google.android.gms:play-services-maps:9.0.0'
   compile 'com.google.android.gms:play-services-location:9.0.0'
   compile 'com.android.support:cardview-v7:23.4.0'
   compile 'com.getbase:floatingactionbutton:1.10.1'
   compile 'com.squareup.picasso:picasso:2.5.2'
   compile 'com.android.volley:volley:1.0.0'
   compile 'com.google.firebase:firebase-messaging:9.0.0'
   compile 'com.android.support:multidex:1.0.1'
   

   apply plugin: 'com.google.gms.google-services'

我的清单文件在这里

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:name="android.support.multidex.MultiDexApplication"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
<activity android:name=".Util.DisconnectedNetwork"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.Transparent"></activity>

    <service android:name=".FCM.FirebaseMessagingHandler">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

    <service android:name=".FCM.FirebaseRegistrationTokenHandler">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

</application>

将堆大小增加到 2048M 后。 Gradle 报此错误

错误:任务 ':app:transformClassesWithDexForDebug' 执行失败。 com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: 方法 ID 不在 [0, 0xffff] 中: 65536

我按照 android 开发者网站上的所有说明进行操作,但仍然遇到此问题。如何解决这个问题?

【问题讨论】:

我认为使用multidex应该是最后的选择,因为它会使构建过程非常“繁重”。尝试删除一些依赖项:您正在使用compile 'com.google.android.gms:play-services-maps:9.0.0'compile 'com.google.android.gms:play-services-location:9.0.0',但它们已经包含在compile 'com.google.android.gms:play-services:9.0.0' 中。另外,不要加载所有播放服务,因为 google 将其拆分为更小的部分,严格包含您需要的内容 【参考方案1】:

我的应用遇到了类似的错误,因此我在 Android Studio 中安装了一个名为 Methods Count (http://www.methodscount.com/) 的插件。它显示了每个依赖项使用的方法引用的数量,并显示了编译路径

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

有超过 69,000 个引用自己

我将其更改为显示您的依赖项之一:

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

它显示 69,520 个方法引用 作为此编译路径的依赖项。

您可能没有使用编译路径的范围,并且可能能够指定更集中的路径以消除大量使用的方法引用并获得低于 65k 的最大值。个性化服务列表为here。

就我而言,我只能想象大约一年前,当我将 Firebase 整合到我的应用中时,我添加了 gms 服务行,但在 Firebase 网站上找不到相同的参考。

刚刚意识到对您的问题的评论与将依赖关系分解为您需要的内容类似。

【讨论】:

【参考方案2】:

你需要在android默认配置中启用multidex然后:

android 
    compileSdkVersion 23
    buildToolsVersion '23.0.3'

    defaultConfig 
        applicationId "com.example.case"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 43
        versionName "4.0.13"

        // Enabling multidex support.
        multiDexEnabled true
    

在日常构建应用程序时,通常使用debug 默认风格。因此,如果您的应用程序有超过 65k 的方法,则需要在所有版本上都不要启用它。

附带说明一下,您可能希望在调试版本中使用 Proguard,这样您就不必在其上启用 multiDex。

完整的应用程序/build.gradle (documentation)

android 
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig 
        ...
        minSdkVersion 14
        targetSdkVersion 21
        ...

        // Enabling multidex support.
        multiDexEnabled true
    
    ...


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

最后一部分:在清单中添加 MultiDex 应用程序(或作为您自己的父级Application

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

【讨论】:

【参考方案3】:

你为发布风格启用了 mutlidex,你也应该为调试风格启用这一行

debug 
    multiDexEnabled true


release 
    shrinkResources true
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    multiDexEnabled true

【讨论】:

以上是关于.dex 文件中的方法引用数超过 64K的主要内容,如果未能解决你的问题,请参考以下文章

.dex 文件中方法引用的数量不能超过 64k API 17

安卓应用方法数超过64k解决办法:分割Dex

DEX 方法超过64K限制和gradle编译OOM问题解决

android 方法数超过65k,解决dex方法数超过65536

Android 方法数 65k 限制与 LinearAlloc 限制

解决Android单个dex文件不能超过65535个方法问题