La aplicación de Android se reduce más allá de R8 | por A Pilgun

¡Hola todos! Mi nombre es Aleksandr y estoy trabajando en la reducción de ACV, una forma más efectiva de reducir las aplicaciones de Android. ¡Prueba! En resumen, la reducción de ACV ayuda a eliminar el exceso de código de bytes de las aplicaciones de Android al eliminar el código no utilizado. Requiere pruebas exhaustivas en comparación con las herramientas existentes basadas en análisis estático. Pero solo el código ejecutado llega al APK. A partir de este artículo, obtendrá información sobre el funcionamiento interno de la aplicación, cómo está cambiando la aplicación con la reducción de R8 y cómo aprovechar la cobertura de comandos para superar a R8. ¡Siéntase libre de hacer clic en nuestros informes de cobertura al final de este artículo!El tamaño de la aplicación siempre ha sido importante para los creadores de aplicaciones, ya que afecta las tasas de instalación. Por otro lado, una rica experiencia de interfaz de usuario es una ventaja competitiva que aumenta el tamaño. Entre las herramientas, R8 Shrinker y ProGuard son más conocidas por la reducción de tamaño. Además, Facebook lanzó su propio optimizador llamado ReDex. Identifican y eliminan código estáticamente inalcanzable y aplican otras optimizaciones inteligentes. Estas herramientas ayudan mucho. Sin embargo, los APK aún contienen una gran cantidad de código accesible pero nunca ejecutado. Para esta demostración, primero produciremos la aplicación WebView más pequeña. Más adelante agregaremos notificaciones en segundo plano para monitorear los cambios gradualmente. ¡Una actividad y unas pocas líneas de código para abrir su página web y listo!la clase pública MainActivity amplía la actividad {@Overrideprotected void onCreate(Bundle SavedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.am);WebView w = (WebView) findViewById(R.id.web);w.setWebViewClient( new WebViewClient(){//Android anterior aún necesita esta función obsoleta @ Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {return false;}});w.loadUrl(«https://debloat.app»);w. getSettings().setJavaScriptEnabled(true);// Esta línea habilita las notificaciones (para la versión completa)FirebaseMessaging.getInstance().subscribeToTopic(«news»);}}Resulta que Android Studio viene con 1-5 MB APK por defecto para aplicaciones simples generadas. Entonces, primero, eliminemos las dependencias y los recursos predeterminados y limpie el archivo AndroidManifest. Otro truco de magia es colocar un solo vector xml para un icono. Siguiendo esta receta, nuestra APK solo pesa (861 para DEX). Esto se duplica a 20 KB cuando se publica en Google Play. ¡Intentalo! Ahora agreguemos la dependencia de mensajería de Firebase. Resultó que la dependencia de Firebase requiere la biblioteca compatible de AndroidX. Por lo tanto, el tamaño completo de la aplicación salta a 1,1 MB (882 KB para DEX).Contenido completo de la aplicación (apkanalyzer)Funciones internas completas de la aplicación (apktool) Apkanalyzer revela las funciones internas de la aplicación, pero también usamos Apktool para ver más. La aplicación completa contiene paquetes adicionales de alto nivel (además del paquete principal «app.debloat») y muchas clases. ¡Vamos a encogerlo! Para hacer nuestra aplicación más pequeña, activemos R8 en modo completo y reconstruyamos la aplicación. Aquí está la tabla de comparación.Comparación de tamaño antes y después de los ajustes de R8Nombres de clase/paquete minificados en R8 El tamaño de la aplicación mejoró en un 67 %. Además, la estructura del código también cambió drásticamente. Visualmente, en lugar de paquetes/clases/métodos/nombres de variables legibles por humanos, obtuvimos nombres cortos. Sin embargo, el número de entidades de código también se ha reducido considerablemente.Comparación de entidades de código y recursos Puede pensar que necesitamos todo esto. Pero ciertamente encontraremos el código y los recursos redundantes aquí. Por ejemplo, fue inesperado encontrar 122 archivos XML y 41 PNG adicionales. Resultó que la mayoría de los archivos XML contienen traducciones de errores de indisponibilidad del servicio Google Play. ¡Esta funcionalidad se aplica a casi todas las aplicaciones! Puedes decidir por ti mismo sobre la utilidad 🙂Carpeta de recursos de APK.Ejemplo ./res/values/strings.xml Tenga en cuenta que se hace referencia a los recursos y se usan en alguna parte del código. Hay demasiado código, pero en la versión pudimos ver paquetes, clases, métodos y campos en la aplicación completa. R8 reduce la cantidad de código, aunque también es más difícil obtener una indicación del código minimizado. De hecho, podemos ver lo que se está ejecutando con la cubierta de instrucciones. ACVTool es una herramienta de medición de cobertura de instrucciones que resalta el código realmente ejecutado en un informe similar a JaCoCo, pero para toda la aplicación y en pequeña escala. Omitiremos todos los detalles técnicos y nos sumergiremos directamente en la cobertura instructiva generada a partir de las pruebas de extremo a extremo. Tenemos un informe para cada versión de la aplicación: para la aplicación inicial de 1,1 MB y para la R8 optimizada (366 KB).Resultados de la cobertura completa de la aplicación (1,1 MB).Aplicación R8 optimizada (366 KB) Resultados de cobertura El código real ejecutado parece ser solo del 7,6 % para la aplicación no optimizada. Sin embargo, para la aplicación optimizada para R8, crece al 27,5 %. Veamos cómo ha cambiado el paquete principal.Clases del paquete principal antes y después de reducir R8 Resulta que R8 dejó solo la clase MainActivity en el paquete principal. Por supuesto, se hace referencia a esta clase en el archivo de manifiesto. Pero la clase también ha cambiado.Método MainActivity.onCreate antes y después de reducir R8. La clase MainActivity en realidad tiene más declaraciones en el método onCreate. Aparentemente, el código en línea R8 de otros métodos. ¡Incluso podemos encontrar una estructura de intento y captura aquí! Sin embargo, la mayor parte de la aplicación (~73% de las instrucciones) no se ejecutó a pesar de nuestros esfuerzos de prueba. Con la información de cobertura de instrucciones, ahora sabemos exactamente qué se ejecutó. Este código debe permanecer. Sin embargo, acortamos cuidadosamente las instrucciones no ejecutadas. De esta manera, la versión reducida de ACV produce una cobertura de instrucciones de casi el 100 por ciento y ahora pesa 277 KB.Aplicación reducida R8 y ACV (277 KB), resultados de coberturaAplicación reducida R8 y ACVresultados de reducción general

Terminamos con una aplicación de 277 KB, que es un 24 % más pequeña que la versión optimizada para R8. En general, esto es un 75 % menos que el APK original (y un 91 % menos para DEX).

Sin embargo, las manipulaciones de bytecode son una tarea bastante desafiante. Nuestro enfoque automatizado aún contiene algunas clases vacías y definiciones de métodos con instrucciones eliminadas: métodos de código auxiliar. Los stubs nunca se invocan, pero algunos de ellos pueden mantener la estructura del código a través de la herencia.Métodos de stub Aunque en este informe nos enfocamos en eliminar sentencias no ejecutadas, eventualmente se eliminan stubs. Todavía hay espacio para otras optimizaciones. Este trabajo está en progreso.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.