【问题标题】:Redundant resource referances in multiple R.java causes DexIndexOverflowException多个 R.java 中的冗余资源引用导致 Dax Index OverflowException
【发布时间】:2017-10-18 07:38:57
【问题描述】:

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

我的应用获取

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

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

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

编辑:

我不会使用 multi-dex,它不能解决我的问题。我想删除多余的字段 ID。

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

【问题讨论】:

    标签: android r.java-file dex


    【解决方案1】:

    就像@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】:

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

    • Android 有预定义的上limit of Methods of 65536

    什么时候?

    DEX 文件的方法索引大小为 16 位,也就是说 65536 表示可以调用的引用总数 单个 DEX 文件中的代码。如果克服了就会出现这个错误。

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

    怎么样?不使用 multiDex

    ProGuard 优化字节码,删除未使用的代码指令,并 用 short 混淆剩余的类、字段和方法 names.Resource 收缩可用于 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 规则的地方。

    资源缩减

    资源收缩只能与代码收缩结合使用。在代码收缩器移除所有未使用的代码后,资源收缩器可以识别应用仍在使用哪些资源。

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

    【讨论】:

    • com.android.support:multidex:1.0.1 仅适用于 api 19 及更低版本。实际上从来没有为我工作过,我在 api 19 上使用 multidex 没有成功。我以发布版本的 Proguard 收缩规则结束(然后它在没有 multidex 的情况下工作)
    • @user1209216 在我的情况下,它永远不会通过添加 multidex 来工作,但我可以通过做一些调整来使其工作。虽然这个答案对操作没有帮助。
    • 不要保留整个包! 支持库应用自己的简约 proguard 规则,比您的建议更优化。
    【解决方案3】:

    通过在 Module build.gradle 中添加“multiDexEnabled true”解决了我的问题。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2018-01-01
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      相关资源
      最近更新 更多