【问题标题】:How to avoid DEX 64K LIMIT by importing the right library如何通过导入正确的库来避免 DEX 64K LIMIT
【发布时间】:2016-05-12 15:52:33
【问题描述】:

在编译我使用的所有库时,我遇到了 Dalvik 中的 64k 方法限制 溢出的问题。我在导入支持库时开始遇到这个问题,因为有些已经包含在其他库中,最终超出了限制。

有没有办法验证一个库是否在当前项目中未使用或已经通过另一个库依赖项导入?

目前,我排除了我确定认识的人,但必须手动执行此操作似乎很奇怪。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:multidex:1.0.1'
    compile "com.android.support:percent:${supportLibVersion}"
    compile("com.android.support:design:${supportLibVersion}") {
        exclude module: 'support-v4'
    }
    compile("com.android.support:cardview-v7:${supportLibVersion}") {
        exclude module: 'support-v4'
    }

    compile('com.github.nkzawa:socket.io-client:0.4.1') {
        exclude group: 'org.json', module: 'json'
    }
    compile('com.astuetz:pagerslidingtabstrip:1.0.1') {
        exclude module: 'support-v4'
    }
//...
}

目前的解决方案:

  1. 使用 Gradle 插件 - 前段时间我们编写了一个非常易于使用的 Gradle 插件,它按包列出了方法的数量以及总数。您可以在此处找到有关它的更多信息。
  2. www.methodscount.com – 想知道特定库将向您的应用程序添加多少方法?只需在这个网站上输入“编译”语句,它就会告诉你它的方法数、依赖项、JAR 大小和 DEX 大小。
  3. Android Studio 插件 - 这个出色的插件显示了 Android Studio 中每个依赖项的方法数。
  4. 使用 MultiDex 支持库 如果您使用的是 Android Studio,则该过程非常简单。如果您不是,我强烈建议您迁移,因为 Google 可能很快就会放弃对 Eclipse ADT 插件和旧的基于 Ant 的构建系统的支持。

第 1 步

在 build.gradle 中添加 MultiDex 支持库的依赖项

dependencies { 
... 
   compile 'com.android.support:multidex:' 
   ... 
}

第 2 步

通过在 gradle 配置的 buildType 或 productFlavor 部分中设置 multiDexEnabled 标志来启用多索引。

defaultConfig { 
   ... 
multiDexEnabled true 
... 
}

现在根据您的项目,您有 3 个选项:

如果您还没有创建自己的应用程序类,只需在AndroidManifest.xml 中将android.support.multidex.MultiDexApplication 声明为您的应用程序类

   .... 
   android:name="android.support.multidex.MultiDexApplication" 
   ... 

如果您已经有自己的 Application 类,请将其扩展为 android.support.multidex.MultiDexApplication 而不是 android.app.Application

如果您的 Application 类正在扩展某个其他类并且您不想或无法更改它,请覆盖 attachBaseContext(),如下所示:

public class MyApplication extends FooApplication { 
   @Override 
   protected void attachBaseContext(Context base) { 
      super.attachBaseContext(base); 
      MultiDex.install(this); 
   } 
}

【问题讨论】:

  • 您可以使用methodscount.com。它列出了每个库的依赖项并显示每个依赖项的方法计数。还有一个gradle插件。
  • 那个网站太神奇了!谢谢男人
  • @Jaythaking 你检查我的答案了吗?

标签: android gradle android-support-library android-appcompat android-multidex


【解决方案1】:

您可以打开终端并运行命令 gradlew app:dependencies 以测试哪些依赖项已作为您的项目的传递依赖项包含在其他依赖项中,以及每个依赖项的各自版本。

例如,我为我使用的 com.android.support:design 库的一个项目获得了以下依赖关系图表:

+--- com.android.support:design:23.3.0
|    +--- com.android.support:appcompat-v7:23.3.0
|    |    +--- com.android.support:support-vector-drawable:23.3.0
|    |    |    \--- com.android.support:support-v4:23.3.0
|    |    |         \--- com.android.support:support-annotations:23.3.0
|    |    +--- com.android.support:animated-vector-drawable:23.3.0
|    |    |    \--- com.android.support:support-vector-drawable:23.3.0 (*)
|    |    \--- com.android.support:support-v4:23.3.0 (*)
|    +--- com.android.support:support-v4:23.3.0 (*)
|    \--- com.android.support:recyclerview-v7:23.3.0
|         +--- com.android.support:support-v4:23.3.0 (*)
|         \--- com.android.support:support-annotations:23.3.0

【讨论】:

  • 我如何删除传递依赖或重复项?
  • 您排除组/模块的方法是正确的。只有您需要识别应用程序所需的(传递)依赖项(及其版本)并排除不需要的依赖项。作为下一步,您可以使用 Proguard 从打包的应用程序中删除未使用的类、字段、方法和属性,包括来自包含的代码库的那些(使其成为解决 64k 引用限制的有价值的工具)。详情请见developer.android.com/studio/build/shrink-code.html
  • 当我尝试从 com.android.support:design:23.3.0 中排除 'support-v4' 时,在执行 gradlew app:dependencies 时它仍然存在......为什么会这样?
  • 从设计中排除 support-v4 可能不是一个好主意。让那部分使用proguard进行优化。但是 support-v4 也可能是通过任何其他依赖项的传递依赖项。
  • 祝你在没有支持-v4 的情况下运行 c̶o̶m̶p̶i̶l̶e̶ 祝你好运。
【解决方案2】:

你可以试试我的技巧,它可能对你有用

  1. 首先,您应该避免使用外部库。就像那个库具有相同的依赖项一样。因此,尝试将该库与 android 应用程序代码合并。 因此为方法节省了很多空间。

  2. 使用有用的依赖项和库,例如,如果您想要 google play 服务,则只包含有用的服务而不是全部。参见示例

    compile "com.google.android.gms:play-services-location:9.4.0"
    compile "com.google.android.gms:play-services-maps:9.4.0" 
    

避免这种情况

compile 'com.google.android.gms:play-services:9.4.0'
  1. 删除不需要的依赖项。在代码中使用非常可选的依赖项。

  2. 如果一切都不是很好,那么在你的代码中使用 multidex。但它会创建多个 dex 文件。所以,你的代码将花费很多时间来编译。

谢谢,希望对你有帮助。

【讨论】:

  • 我听不懂你的 1 号?您建议避免使用外部库吗?
  • 是的,这意味着如果您使用了一些模块并且包含与 v7 相同的依赖项,并且您在应用程序端使用了相同的依赖项。因此,最好在代码中使用这些模块。这样可以避免重复库并节省大量空间。有时它发生了,但大多数情况下我们都忽略了这件事。
【解决方案3】:
 defaultConfig
 {    
     multiDexEnabled true 
 }

 dependencies {
     compile 'com.android.support:multidex:1.0.0'
 }

并将此方法添加到您的应用程序类中

@Override
protected void attachBaseContext(Context newBase) {

    super.attachBaseContext(newBase);

    MultiDex.install(this);
}

【讨论】:

    【解决方案4】:

    点击File然后点击Project Structure点击弹出窗口左下角的app。您将看到多个选项卡单击Dependencies选项卡然后单击右上角的加号选择库依赖项搜索您想要的库它会显示那些库在您的 IDE 中可用

    【讨论】:

      【解决方案5】:

      虽然使用Multidex Support Library 库解决了这个问题,但它并不完美。首先要做的应该是确定您的应用程序当前有多少方法,以及每个依赖项添加了多少方法。之前您必须手动执行此操作,但现在有很多工具可用:

      1. 使用 Gradle 插件 - This 是一个非常容易使用的 Gradle 插件,它按包列出了方法的数量以及总数。你可以找到更多关于它的信息here
      2. www.methodscount.com – 只需在本网站上输入 ‘compile’ 语句,它就会告诉你它的方法数、依赖关系、JAR 大小和 DEX 大小。
      3. Android Studio 插件 – 这个出色的 plugin 显示了 Android Studio 中每个依赖项的方法计数。

      不管你最终使用什么工具,使用它的信息 提供对您的应用程序的依赖项进行审计。你应该 寻找未使用的库或可以最小化甚至 替换为您自己更简单的解决方案。如果您没有使用Proguard 要删除未使用的代码,首先启用它并查看它是否解决了 问题(检查this)。使用Proguard 很好……不好玩,但一旦你成功了 它工作正常,它会显着减少方法数。我摔倒 否则失败,您将不得不使用 MultiDex 支持库。

      查看gradle 任务以去除 Google Play 服务库中未使用的包。

      结论

      虽然Multidex Support Library 在大多数情况下修复了 DEX 64K 问题,但应将其视为最后的手段。在尝试使用它之前,您应该审核您的项目是否存在不需要的依赖项,并使用ProGuard 删除尽可能多的未使用代码。如果您继续使用它,请确保在旧设备上测试您的应用程序。

      希望这会对你有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-29
        • 1970-01-01
        • 1970-01-01
        • 2017-09-09
        • 2022-11-20
        • 2021-12-07
        • 1970-01-01
        相关资源
        最近更新 更多