AS: 3.5.3; Complemento Android Gradle: 3.5.0; Gradle: 5.6.2;
Observamos un aumento drástico en el número de métodos referenciados en nuestra aplicación después de dividir el módulo 'aplicación' en varios módulos pequeños. Pero lo extraño es que la adición de métodos referenciados por cada clase es menor que el total mencionado en Android Apk Analyzer Tool.
Para fines de prueba, he movido WebActivity.class del módulo 'aplicación' al módulo 'adaptadores' y el número de métodos referenciados aumentó en 181 métodos.
Para resumir:
app / WebActivity = 63546 Métodos reales referenciados pero que muestran 65394 métodos. adaptador / WebActivity = 63543 Métodos reales referenciados pero que muestran 65575 métodos.
Hemos observado que el 'recuento de métodos referenciados' aumentó en casi 10k después de agregar / dividir 4 nuevos módulos.
¿Cuál es el problema exacto?
¿Cómo la modularización de la aplicación puede aumentar el recuento de métodos referenciados tan drásticamente?
A continuación se muestran las capturas de pantalla que tomé de dos diferencias diferentes de solo APK: WebActivity se movió del módulo 'aplicación' al módulo 'adaptador' y aumentaron 181 métodos de referencia:
WebActivity en el módulo 'app'
Se movió WebActivity al módulo 'adaptador'
En las capturas de pantalla, ¿por qué la adición de métodos referenciados por cada clase (marcados en color rojo) no es igual al total dado en Apk Analyzer?
fuente
Respuestas:
He estado leyendo sobre el rendimiento del código y los parámetros de ajuste durante mucho tiempo. De hecho, los programas de Android son uno de mis enfoques.
Vamos a introducir al principio los conceptos básicos o más importantes en los que nos ayudan a llegar a una solución.
Como ha declarado el desarrollador de Android
Por lo tanto, los módulos tienen sus propias dependencias y dependencias . Y puede explorarlo en el proyecto
Hierarchy Viewer
.De hecho, el énfasis de la modularización en el mantenimiento es importante. A diferencia de Performance Matters, porque la modularización tiene este importante impacto:
Aquí hay un diagrama que tracé para aclararlo. Como puede ver, mientras usa un módulo discreto, para invocar el Método A, se
2N micro secs
compara con unN micro secs
módulo discreto.Esta pregunta me viene a la mente de que los métodos referenciados cuentan lo que se relaciona con la profundidad de la herencia.
La respuesta es: aunque el uso de la modularización aumenta los métodos de referencia, pero en realidad no afecta el rendimiento de la aplicación y el principal problema posible es la profundidad de la herencia, que en la mayoría de los casos es ignorable .
Hago hincapié en que el aumento de los métodos de referencia en la modularización se debe a cada módulo Gradle y dependencias
Condiciones en las que el analizador de APK de impacto es importante Métodos de referencia
Además de la declaración oficial anterior, quiero agregar otra condición en la que impacta el analizador APK que es:
¿Cuánto tiene experiencia el desarrollador en modularización?
La modularización es como un hogar en el que la arquitectura (desarrollador) define dónde debería estar la cocina y dónde debería estar el baño y dónde debería estar el WC. ¿Qué pasa si la arquitectura decide combinar WC y cocina? Sí, esto es un desastre.
Esto puede suceder durante la modularización si el desarrollador no tiene mucha experiencia.
Respondiendo a preguntas de OP Además de información adicional
Aquí respondo a las preguntas frecuentes en los comentarios
Debido a que los módulos se pueden construir, probar y depurar, DEBEN tener sus propios Gradle & Dependencies.
Mientras se cumple el proyecto de varios módulos, el compilador genera varios
.dex
archivos que incluyen:.dex
archivo para dependencias totalmente integradas.dex
mEl
.dex
archivo de dependencias es una integración de todos los módulos graduados¡Veamos cómo un módulo gradle impacta el conteo final de Mothods referenciado!
hay 2
APK
s con el mismo resultado pero diferencia en los recuentos de métodos referenciados.Ambas son actividades vacías que tienen una
1.7k
diferencia en el recuento de métodos referenciados que es muy alta dependiendo de su funcionalidad. La diferencia clave está en Gradle de su módulo, uno de ellos fue configurado paraOtro configurado para
Aunque son solo actividades vacías, pero una diferencia mínima en Gradle causó una
1.7k
diferencia en los recuentos de métodos referenciados.Y App Gradle es
Esto es solo un filtro IDE, nada más. seguro, si solo selecciona un
.dex
archivo, el método de referencia cuenta es igual a la SUMA de cada fila del método de referencia cuenta, pero si selecciona varios.dex
archivos, verá la diferencia en SUMA y el conteo real debido a la igualdad en las referencias que el analizador prefirió filtrarlosen sus capturas de pantalla seleccionó varios
.dex
archivos y luego la igualdad de filtro del analizador.Teóricamente NO debería aumentar los recuentos de métodos referenciados. PERO , como lo expliqué, Developer Experience tiene un gran impacto en el resultado final.
Team Analyzer debe verificar y corregir los problemas de rendimiento antes del lanzamiento como
Ahora quiero aclarar cómo la experiencia del desarrollador y el mantenimiento del código afectan el resultado final. INCLUSO si su APK utiliza dependencias centralizadas
en el ejemplo anterior, he aumentado
5.1k
en el recuento de métodos referenciados ¡¡¡ INCLUSO SI tuviera dependencias centralizadas !!!!!Como es posible ?
La respuesta es: acabo de agregar un
.jar
archivo inútil y oculto en ellibs
directorio del proyecto. tan fácil como puedes ver, afecté el resultado final.Como puede ver, la experiencia del desarrollador afecta el resultado final. Como resultado, prácticamente es posible que los métodos referenciados aumenten aunque, en teoría, NO deberían .
La compilación no tiene ninguna relación con los métodos referenciados. Cumple con lo que el desarrollador quiere cumplir.
Conclusión
He cubierto todas las posibilidades en torno al tema. De hecho, puede surgir de diferentes situaciones y un desarrollador al usar esta guía puede solucionar el problema.
NOTA IMPORTANTE: casi todas las declaraciones son mi investigación e investigaciones. de hecho, puede haber errores y fallas y se actualizarán para agregar mucha más información en el futuro.
fuente
Respondiendo a mi propia pregunta como la solución simplemente hizo clic en mi mente, aunque esto no se ha intentado pero funcionaría, definitivamente o muy probablemente. :) La respuesta dada por Mr.AF fue muy útil para llegar a una solución final. Habla de ¿Por qué? pero no cómo evitarlo o cómo mejorarlo.
Aquí hay una manera de recuperar el recuento de método referenciado original / real :
No depende de cómo modularizamos la aplicación, sino de cómo agregamos dependencias. Si agregamos una dependencia usando ' implementación ', esa dependencia permanece privada para el módulo y ningún otro módulo puede usarla. Y si agregamos la misma dependencia usando ' api ' (igual a 'compilación' obsoleta), entonces se vuelve pública y otros módulos dependientes pueden usarla. Dado que estamos usando 'implementación' para agregar dependencias en cada módulo en un proyecto de varios módulos, cada módulo tiene todas las dependencias requeridas como autónomas, esta es la razón por la que se puede compilar individualmente. Esto da como resultado una disminución del tiempo de compilación / compilación, ya que solo se pueden compilar módulos modificados. Pero, el uso de 'implementación' aumenta el recuento de métodos referenciados ya que hay muchos métodos duplicados referenciados.
Entonces, si el tiempo de compilación no es su preocupación, pero el recuento de métodos referenciados sí lo es, puede dibujar el árbol de dependencias de todos los módulos y evitar agregar dependencias duplicadas usando 'api' en el módulo base. De esta manera, incluso el módulo superior puede usar la dependencia agregada por el módulo base, lo que evitará duplicados. Recuerde, esto aumentaría el tiempo de construcción.
Podemos lograr ambos si pudiéramos distinguir las dependencias para la depuración y la compilación de la versión . Agregue todas las dependencias utilizando 'implementación' para la compilación de depuración y agregue solo las dependencias necesarias y optimizadas para la compilación de lanzamiento utilizando 'api' . De esta forma, la compilación de depuración será más rápida y la compilación de lanzamiento será más lenta, lo que es asequible.
Nota: Actualizaría esta respuesta una vez que descubra cómo proporcionar dependencias separadas para la depuración y la versión de compilación.
fuente
Veo toda la diferencia en su paquete 'com'. Puede ampliar y comparar qué clases exactas se redujeron. Si compila con el último R8, puede eliminar parte del código por defecto. Cuando coloca algunas clases en el módulo de reducción, no sabe si las clases / métodos públicos se pueden eliminar o si deben permanecer para su uso en otro módulo.
fuente