--main-dex-list中的类太多,超过了主要dex容量 [英] Too many classes in --main-dex-list, main dex capacity exceeded

查看:463
本文介绍了--main-dex-list中的类太多,超过了主要dex容量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试运行测试用例,但在进行dex转换时出现以下错误 超出预期的最高级别:

I'm trying to run instrumentation test cases but getting the below error while dex conversion UNEXPECTED TOP-LEVEL EXCEPTION:

com.android.dex.DexException: Too many classes in --main-dex-list, main dex capacity exceeded
        at com.android.dx.command.dexer.Main.processAllFiles(Main.java:494)
        at com.android.dx.command.dexer.Main.runMultiDex(Main.java:334)
        at com.android.dx.command.dexer.Main.run(Main.java:244)
        at com.android.dx.command.dexer.Main.main(Main.java:215)
        at com.android.dx.command.Main.main(Main.java:106)

:App:dexDebug FAILED

如何在gradle中解决此问题?

How to resolve this issue in gradle?

推荐答案

让我们首先了解该问题:

Let's first understand the problem:

在Lollipop之前的设备上,框架仅加载主dex.要支持多dex应用程序,您必须使用所有辅助dex文件显式修补应用程序类加载器(这就是为什么您的Application类必须扩展

On pre-Lollipop devices, only main dex is being loaded by the framework. To support multi-dex applications you have to explicitly patch application class loader with all the secondary dex files (this is why your Application class have to extend MultiDexApplication class or call MultiDex#install).

这意味着您的应用程序的主dex应该包含在对类加载器进行修补之前可以访问的所有类.

This means that your application's main dex should contain all the classes that are potentially accessible before class loader patching.

如果您的应用程序代码尝试引用一个​​ java.lang.ClassNotFoundException ,您将收到​​ java.lang.ClassNotFoundException 在成功修补应用程序类加载器之前,将这些类打包在您的辅助dex文件之一中.

You will receive java.lang.ClassNotFoundException if your application code will try to reference a class that was packaged in one of your secondary dex files before successfully patching application class loader.

我已经在此处记录了插件如何决定应在main-dex中打包哪些类.
如果这些类引用的方法总数超过了65,536个限制,则构建将失败,并显示Too many classes in --main-dex-list, main dex capacity exceeded错误.

I've documented here how plugin decides which classes should be packaged in main-dex.
If total amount of methods that those classes are referencing exceeds the 65,536 limit, then build will fail with Too many classes in --main-dex-list, main dex capacity exceeded error.

我可以考虑针对此问题的三种可能的解决方案:

I can think of three possible solutions for this issue:

  1. (最简单的解决方案,但不适用于大多数 应用程序)将minSdkVersion更改为21.
  2. 缩小您的应用程序代码.之前对此进行了多次讨论(请参阅此处此处).
  3. 如果上述解决方案都不适合您,则可以尝试使用
  1. (The easiest solution, but not suitable for most of the applications) Change your minSdkVersion to 21.
  2. Shrink your application code. This was discussed many times previously (see here and here).
  3. If none of the above solutions work for you, you can try to use my workaround for this issue - I'm patching the Android gradle plugin to not include Activity classes in main dex. It's a bit hacky, but works well for me.

Android Bug Tracker中有关于此错误的问题 .希望工具团队能够尽快提供更好的解决方案.

There's an issue in Android bug tracker regarding this error. Hopefully the Tools team will provide a better solution soon.

更新(2016/4/27)

Gradle插件的2.1.0版允许过滤main-dex列表类.
警告:这使用的是不受支持的api,将来会被替换.

Version 2.1.0 of Gradle plugin allows to filter main-dex list classes.
Warning: this is using an unsupported api that will be replaced in the future.

例如,要排除所有活动类,可以执行以下操作:

For example, to exclude all activity classes you can do:

afterEvaluate {
  project.tasks.each { task ->
    if (task.name.startsWith('collect') && task.name.endsWith('MultiDexComponents')) {
      println "main-dex-filter: found task $task.name"
      task.filter { name, attrs ->
        def componentName = attrs.get('android:name')
        if ('activity'.equals(name)) {
          println "main-dex-filter: skipping, detected activity [$componentName]"
          return false
        } else {
          println "main-dex-filter: keeping, detected $name [$componentName]"
          return true
        }
      }
    }
  }
}

您还可以查看我的示例项目演示了此问题(并应用了上述过滤条件.)

You can also check my example project that demonstrates this issue (and applies the above filtering).

更新2(2016年7月1日)

Gradle插件的版本2.2.0-alpha4(带有构建工具v24)最终通过示例项目,表明该构建现在可以成功完成,而无需任何自定义构建逻辑.

Version 2.2.0-alpha4 of Gradle plugin (with build-tools v24) finally solves this issue by reducing multidex keep list to a minimum.
The unsupported (and undocumented) filter from 2.1.0 should not be used anymore. I've updated my sample project, demonstrating that build succeeds now without any custom build logic.

这篇关于--main-dex-list中的类太多,超过了主要dex容量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆