Límite de métodos 64K por un archivo dex en Android
Me enfrenté a este problema java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536
y decidí excluir algunos métodos de un archivo dex. Mi gradle.build:
compile ('com.google.android.gms:play-services:+') { exclude group: "com.google.android.gms.analytics" exclude group: "com.google.android.gms.games" exclude group: "com.google.android.gms.plus" exclude group: "com.google.android.gms.drive" exclude group: "com.google.android.gms.ads" }
Creo que este fragmento de código es incorrecto, porque no hay method ID not in [0, 0xffff]...
error method ID not in [0, 0xffff]...
¿Cómo puedo excluir partes innecesarias del servicio de Google Play? Utilizo sólo mapas y GCM.
- ¿Se ha producido un error "Esta aplicación se ha creado con una configuración incorrecta" en algunos teléfonos?
- Gradle resValue causa recursos de cadena duplicados
- ¿Cuál es la diferencia entre proguard-android.txt y proguard-rules.pro? - Android
- Error de compilación de Gradle (Android Studio 2.2.2)
- Dependencias transitivas para la biblioteca aar local
Actualizado.
Gracias reVerse. Es un código realmente útil. Hay un script para obtener la cuenta de los métodos (también puede ver los nombres de los paquetes existentes) https://gist.github.com/JakeWharton/6002797 ( source ./dex.sh; dex-method-count-by-package test.apk
)
Antes de usar el fragmento de código de la respuesta de reVerse
Count of methods / Package ... 22484 com.google.android.gms 2 com.google.android.gms.actions 578 com.google.android.gms.ads 152 com.google.android.gms.ads.doubleclick 25 com.google.android.gms.ads.identifier 86 com.google.android.gms.ads.internal 86 com.google.android.gms.ads.internal.rawhtmlad 86 com.google.android.gms.ads.internal.rawhtmlad.client 88 com.google.android.gms.ads.mediation 4 com.google.android.gms.ads.mediation.admob 73 com.google.android.gms.ads.mediation.customevent 26 com.google.android.gms.ads.purchase 118 com.google.android.gms.ads.search ... 858 com.google.android.gms.games.internal.api 43 com.google.android.gms.games.internal.constants 8 com.google.android.gms.games.internal.data 31 com.google.android.gms.games.internal.events 9 com.google.android.gms.games.internal.experience 215 com.google.android.gms.games.internal.game 56 com.google.android.gms.games.internal.multiplayer 23 com.google.android.gms.games.internal.notification 80 com.google.android.gms.games.internal.player 86 com.google.android.gms.games.internal.request ...
Después de usar el fragmento de código de la respuesta de reVerse, los paquetes: anuncios, juegos y etc se eliminaron.
- Construye el trabajo de Android con connectedInstrumentTest que no funciona en Jenkins
- Java.lang.NoClassDefFoundError: Resolución fallida de: Lorg / jacoco / agent / rt / internal_14f7ee5 / Desconectado
- ¿Por qué los paquetes del módulo de biblioteca no existen en la compilación, incluso cuando Android Studio no muestra errores en el código?
- Com.android.builder.packaging.DuplicateFileException: Archivos duplicados copiados en APK META-INF / maven / com.fasterxml.jackson.core / jackson-databind / pom.xml
- Android studio 0.4.2: Error de sincronización de proyecto de Gradle
- Problema de generación de Gradle 3.0.0-beta1
- De error al generar la aplicación de tarea apk firmada: packageRelease
- Robolectric dice "AndroidManifest.xml no encontrado"
Actualización – Google Play Services 6.5 (12-08-14)
Con la versión 6.5, Google finalmente desagrupó Google Play Services. Así que a partir de ahora será posible compilar selectivamente las API en su ejecutable.
Ejemplo (sólo con las API de AdMob y Android Wear)
compile 'com.google.android.gms:play-services-wearable:6.5.+' compile 'com.google.android.gms:play-services-ads:6.5.+'
Para todas las otras API individuales de Google Play Services, consulta esta página en d.android.com .
Nota: El uso del +
normalmente no se recomienda. A partir de ahora la versión correcta actual sería 6.5.87
. Para obtener más información, vea la publicación oficial del blog (clic) .
Hace algún tiempo ha habido un artículo en Medium.com llamado "[DEX] Sky es el límite? No, 65K métodos es" (definitivamente vale la pena leer), que describe una manera de despojar a los Servicios de Google Play con un script de shell que usted Puede encontrar aquí (google-play-services-strip-script) .
Si bien esto es una opción, también hay una tarea gradle que hace esto para usted:
def toCamelCase(String string) { String result = "" string.findAll("[^\\W]+") { String word -> result += word.capitalize() } return result } afterEvaluate { project -> Configuration runtimeConfiguration = project.configurations.getByName('compile') ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult // Forces resolve of configuration ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library" File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") { inputs.files new File(playServiceRootFolder, "classes.jar") outputs.dir playServiceRootFolder description 'Strip useless packages from Google Play Services library to avoid reaching dex limit' doLast { copy { from(file(new File(playServiceRootFolder, "classes.jar"))) into(file(playServiceRootFolder)) rename { fileName -> fileName = "classes_orig.jar" } } tasks.create(name: "stripPlayServices" + module.version, type: Jar) { destinationDir = playServiceRootFolder archiveName = "classes.jar" from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) { -----> // Specify what should be removed } }.execute() delete { delete (file(new File(playServiceRootFolder, "classes_orig.jar"))) } } } project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task -> task.dependsOn stripPlayServices } }
Nota: se extrae de la tarea Gradle para quitar paquetes no utilizados en la biblioteca de servicios de Google Play @GitHubGist
La parte relevante para usted es donde está la flecha en la task.create(...)
. Hay que especificar qué partes se deben quitar. Así que en su caso sólo escribir algo como esto en allí:
exclude "com/google/ads/**" exclude "com/google/android/gms/analytics/**" exclude "com/google/android/gms/games/**" exclude "com/google/android/gms/panorama/**" exclude "com/google/android/gms/plus/**" exclude "com/google/android/gms/drive/**" exclude "com/google/android/gms/ads/**" exclude "com/google/android/gms/wallet/**" exclude "com/google/android/gms/wearable/**"
Esto eliminará todo, excepto los mapas y GCM-Part.
Nota: Para usarlo, simplemente copie el contenido de la tarea gradle a la parte inferior del archivo build.gradle
del módulo de la aplicación.
- SDK de Android: no escala en el centro del tacto
- ¿Hay una ruta similar a file: /// android_asset / que apunta al directorio de aplicaciones?