多个R.java中的冗余资源referance导致DexIndexOverflowException

时间:2017-10-18 07:38:57

标签: android r.java-file dex

我有多个图书馆项目,他们都依赖于支持图书馆。我的应用程序依赖于这些多个库项目。每个库项目都包含对其 R.java 文件中的库资源的引用。由于冗余,这会使字段ID计数膨胀。

我的应用

  

DexIndexOverflowException:字段ID不在[0,0xffff]中:65536

因为这个冗余的 R.java 引用。

因此我的应用程序有47k方法,而65k字段ID。

修改

我不会使用multi-dex,它不是解决我的问题的方法。我想削减多余的字段ID。

问题不在于如何解决问题,问题在于如何摆脱冗余字段ID。使用multi-dex不会删除冗余字段ID。

3 个答案:

答案 0 :(得分:3)

  

DexIndexOverflowException:字段ID不在[0,0xffff]中:65536

  • Android已预定义上方 limit of Methods of 65536

:当吗

  

DEX文件的方法索引的大小是16位,所以这意味着   65536表示可以调用的引用总数   单个DEX文件中的代码。如果克服则会出现此错误。

一旦开始包含足以导致达到 64K 方法限制的库,就需要删除多余的依赖项。

如何?不使用 multiDex

  

ProGuard优化字节码,删除未使用的代码指令,以及   用short来模糊剩余的类,字段和方法   名称。资源缩减适用于Android插件   Gradle,从您的打包应用中删除未使用的资源,   包括代码库中未使用的资源。它一起工作   代码缩小,以便一旦删除未使用的代码,任何   不再引用的资源也可以安全删除。

如何启用Proguard

minifyEnabled true 添加到build.gradle文件中的相应构建类型。

android {
    buildTypes {
        release { //You can add this in debug mode
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }

}

注意

  1. getDefaultProguardFile('proguard-android.txt') 方法获得了 Android SDK中的默认 ProGuard 设置 tools->proguard->folder

  2. 您可以在 proguard-rules.pro 文件中添加自定义 ProGuard 规则。

  3. 资源缩减

      

    资源缩减仅适用于代码收缩。在代码缩减器删除所有未使用的代码之后,资源缩减器可以识别应用程序仍在使用哪些资源。

    buildTypes {
        release {
                  minifyEnabled true
                  shrinkResources true  //You can add this in debug mode
        }
    }
    

答案 1 :(得分:3)

就像@ intellij-amiya的回答一样,使用multidexproguard将解决您的问题,我个人建议这样做。

如果您不想遵循该方法,则可以手动排除重复的依赖项。

在终端中执行以下命令以查找重复的依赖项。

./gradlew :app:dependencies --configuration compile

或者如果你在Windows上,

gradlew.bat :app:dependencies --configuration compile

:app更改为您的项目名称。

让我们假设你的gradle依赖是这样的:

compile 'com.android.support:support-compat:26.+'
compile 'com.android.support:support-fragment:26.+'

您将获得如下输出:

+--- com.android.support:support-compat:26.+ -> 26.0.0-alpha1
|    \--- com.android.support:support-annotations:26.0.0-alpha1
\--- com.android.support:support-fragment:26.+ -> 26.0.0-alpha1
     +--- com.android.support:support-compat:26.0.0-alpha1 (*)
     +--- com.android.support:support-core-ui:26.0.0-alpha1
     |    +--- com.android.support:support-annotations:26.0.0-alpha1
     |    \--- com.android.support:support-compat:26.0.0-alpha1 (*)
     \--- com.android.support:support-core-utils:26.0.0-alpha1
          +--- com.android.support:support-annotations:26.0.0-alpha1
          \--- com.android.support:support-compat:26.0.0-alpha1 (*)

您可以看到标有(*)的依赖项,并且可以排除这些依赖项。您可以看到support-compat重复,并通过编辑将其排除:

compile ('com.android.support:support-fragment:26.+') {
    exclude module: 'support-compat'
}

重复此操作,直到您的计数低于64k

现在最困难的部分仍然存在。

根据我的经验,排除某些依赖项可能会导致构建失败,运行时异常等。因此,您需要检查应用程序是否正常运行。

希望得到这个帮助。

答案 2 :(得分:-1)

我的问题通过添加" multiDexEnabled true"如下面的Module build.gradle。

android {
          ...
          defaultConfig {
                          ...
                          multiDexEnabled true
                         }
         }