Filtrado de recursos del monolito de Play Services para hacer su APK más pequeño
Se ha escrito mucho sobre la naturaleza monolítica de los Servicios de Google Play y por qué debería dividirse en más bibliotecas. Por ahora la solución para mantener su APK pequeño es usar proguard para quitar las referencias no utilizadas. Esto funciona bastante bien para classes.dex, pero no para los recursos incluidos.
Consigo alrededor de 1 MB de recursos adicionales no utilizados y con una aplicación Android Wear que se acopla. Así que mi APK es 2 MB más grande de lo necesario.
- Gradle connectedAndroidTest devuelve "No se encontró ninguna prueba", sin embargo, el shell adb shell puede encontrar las pruebas
- Paquete de prueba para diferentes sabores en Android Studio
- No se puede crear una aplicación cuando se usa gradle (Android Studio) y local maven repo
- Gradle no pudo resolver
- Creación de una aplicación Android basada en Phonegap en Android Studio
Me pregunto si hay alguna manera directa en Gradle de excluir algunos recursos procedentes de las dependencias AAR del APK resultante.
Parece que las opciones de AAPT en el complemento de Gradle Android sólo permiten filtrar activos .
Estaba pensando en enganchar en algún script aapt personalizado que llamaría a eliminar para una lista de recursos utilizando aapt antes de firmar el APK para la liberación.
¿Alguien más tiene una solución más simple?
- Problema de migración de desarrollo nativo de Android Studio 2.2
- Agrupación de pruebas roboeléctricas utilizando junit Category en un proyecto gradle de Android
- Java.lang.NoClassDefFoundError: com.acme.R $ layout que hace referencia a la biblioteca android
- Obtener Resolver error al importar proyecto en android studio, No se puede cargar la clase 'org.codehaus.groovy.runtime.typehandling.ShortTypeHandling'
- Androidmanifest xml no existe o tiene una etiqueta raíz incorrecta
- Cómo actualizar versiones de Apache HttpClient en Android
- Android: Modo Jumbo vs Multidex
- ¿Cómo puedo ver las tareas de Gradle de Android en Android Studio?
Después de algunas investigaciones encontré la siguiente solución subóptima. Tuve que enumerar todos los recursos no necesarios manualmente (por suerte los patrones son aplicables) y asegúrese también de eliminar todos los archivos donde se hace referencia. A continuación se muestra un ejemplo que hace que mi APK aplicación Wear de 1,5 MB en 300kb y el APK está funcionando normalmente sin problemas.
Tuve que crear mi propia tarea stripResources
y conectarlo entre estándar de Android plug-in de tareas: mergeReleaseResources
y mergeReleaseResources
.
task stripResources << { println "Custom resource stripping in: $buildDir" delete fileTree(dir: "$buildDir", include: "**/layout/confirmation_activity_layout.xml") delete fileTree(dir: "$buildDir", include: "**/layout/watch_card_content.xml") delete fileTree(dir: "$buildDir", include: "**/common_signin*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/common_signin*.xml") delete fileTree(dir: "$buildDir", include: "**/generic_confirmation*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/confirmation_*.xml") delete fileTree(dir: "$buildDir", include: "**/drawable/card_background.xml") delete fileTree(dir: "$buildDir", include: "**/card_frame*.png") delete fileTree(dir: "$buildDir", include: "**/go_to*.png") delete fileTree(dir: "$buildDir", include: "**/drawable/go_to_*.xml") delete fileTree(dir: "$buildDir", include: "**/ic_plusone*.png") delete fileTree(dir: "$buildDir", include: "**/powered_by_google*.png") // if you only have English you can teh following to filter out some GPS texts wich also take few hundreds of kb // delete fileTree(dir: "$buildDir", include: "**/values-*/values.xml") } tasks.whenTaskAdded { task -> if (task.name == 'processReleaseManifest') { task.dependsOn stripResources } }
Puedes hacer una tarea similar para Android APK regular.
A partir de la versión 0.14 del complemento Android Gradle, esto se puede lograr automáticamente como se menciona en este post :
android { buildTypes { release { minifyEnabled true shrinkResources true } } }
shrinkResources
es un indicador que indica al compilador que omita cualquier recurso que no esté referenciado. minifyEnabled
es el nuevo nombre de runProguard
, que debe estar habilitado para que shrinkResources
funcione.
Gracias a la perspicaz respuesta de Petr Nalevka he llegado con la siguiente solución (aka fea hack).
Este código elimina todos los elementos plegables de PNG bajo hdpi, xhdpi, xxhdpi y así sucesivamente, manteniendo sólo los drawables bajo mdpi (los que tienen el tamaño de archivo más pequeño). Dibujos sólo se eliminan si tienen un hermano en mdpi, es decir, si se puede eliminar con seguridad. Los Servicios de Google Play deben seguir funcionando plenamente.
Una tarea se registra para cada variante de aplicación, por lo que este código funciona con múltiples sabores de producto.
applicationVariants.all { variant -> def variantCamelName = variant.name.substring(0, 1).toUpperCase() + variant.name.substring(1) def stripResourcesTask = task("strip${variantCamelName}Resources") { doFirst { def resDir = "$buildDir/intermediates/res/merged/$variant.dirName" def gpsDir = "$buildDir/intermediates/exploded-aar/com.google.android.gms" fileTree(dir: "$gpsDir", include: "**/drawable-*/*.png").each { resFile -> if (!resFile.parentFile.name.endsWith("-mdpi")) { def resName = resFile.name def resDirName = resFile.parentFile.name def mdpiFile = "$resFile.parentFile.parentFile/drawable-mdpi/$resName" if (file(mdpiFile).file) { def files = fileTree(dir: "$resDir", include: "**/${resDirName}/${resName}") // files.each { f -> println "Deleting $f..." } delete files } } } } } tasks["merge${variantCamelName}Resources"].finalizedBy stripResourcesTask }
Probado con Android Studio 1.3.0, Gradle plugin versión 1.3.0, herramientas de compilación versión 22.0.1 y GPS versión 7.5.0.
Soy un poco de un noob Groovy, por lo que esta no es probablemente la solución más elegante.
- ¿Cuál es la diferencia entre windowBackground y el fondo para el estilo de las actividades?
- Cómo escuchar el contacto insertado / actualizado / eliminado en la libreta de direcciones