while unable studio merging error dexing dexarchivemergerexception archives application android-gradle dex

android gradle - unable - Demasiadas clases en--main-dex-list, capacidad de dex principal excedida



gradle multidex (3)

Otra forma de resolver este problema es eliminar las clases con anotaciones en tiempo de ejecución del archivo DEX principal:

android { dexOptions { keepRuntimeAnnotatedClasses false } }

Esto es particularmente útil para aplicaciones que usan marcos de inyección de dependencias, ya que incluso para las anotaciones de Dagger generalmente se mantienen en tiempo de ejecución.

Estoy tratando de ejecutar casos de prueba de instrumentación pero obtengo el siguiente error durante la conversión dex EXCEPCIÓN INESPERADA DE NIVEL SUPERIOR:

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

¿Cómo resolver este problema en gradle?


Primero entendamos el problema:

En dispositivos anteriores a Lollipop, el marco solo carga dex principal. Para admitir aplicaciones multi-dex, debe parchear explícitamente el cargador de clases de aplicaciones con todos los archivos dex secundarios (es por eso que su clase de aplicación debe extender la clase MultiDexApplication o llamar a MultiDex#install ).

Esto significa que el dex principal de su aplicación debe contener todas las clases que son potencialmente accesibles antes del parcheo del cargador de clases.

Recibirá java.lang.ClassNotFoundException si el código de su aplicación intentará hacer referencia a una clase que fue empaquetada en uno de sus archivos dex secundarios antes de parchear con éxito el cargador de clases de la aplicación.

He documentado aquí cómo el complemento decide qué clases deben empaquetarse en main-dex.
Si la cantidad total de métodos a los que hacen referencia esas clases excede el límite de 65.536, la compilación fallará con Too many classes in --main-dex-list, main dex capacity exceeded error.

Puedo pensar en tres posibles soluciones para este problema:

  1. (La solución más fácil, pero no adecuada para la mayoría de las aplicaciones) Cambie su minSdkVersion a 21.
  2. Reduzca el código de su aplicación. Esto se discutió muchas veces anteriormente (ver here y here ).
  3. Si ninguna de las soluciones anteriores funciona para usted, puede intentar usar mi solución para este problema: estoy parcheando el complemento de Android gradle para que no incluya las clases de actividad en la dex principal. Es un poco hacky, pero funciona bien para mí.

Hay un problema en el rastreador de errores de Android con respecto a este error. Esperemos que el equipo de Herramientas proporcione una solución mejor pronto.

Actualización (27/04/2016)

La versión 2.1.0 del complemento Gradle permite filtrar las clases de la lista main-dex.
Advertencia: esto está usando una API no compatible que será reemplazada en el futuro.

Por ejemplo, para excluir todas las clases de actividad que puede hacer:

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

También puede consultar mi proyecto de ejemplo que demuestra este problema (y aplica el filtrado anterior).

Actualización 2 (7/1/2016)

La versión 2.2.0-alpha4 del complemento Gradle (con build-tools v24) finalmente resuelve este problema al reducir la lista de mantenimiento multidex al mínimo .
El filtro no compatible (e indocumentado) de 2.1.0 ya no debería usarse. He actualizado mi proyecto de muestra , demostrando que la compilación tiene éxito ahora sin ninguna lógica de compilación personalizada.


Tienes dos opciones.

  1. use ProGuard para eliminar varios métodos
  2. utilizar la función multidex

Mi consejo: vaya con ProGuard, requiere tan solo cero cambios en el código fuente