La velocidad de inicio de una aplicación es la primera experiencia del usuario. Hay una regla de los ocho segundos en Internet. Si un usuario espera ocho segundos antes de que se abra la aplicación, el 70% de los usuarios dejará de esperar.
1. Iniciar clasificación
Hora de inicio de la aplicación oficial
- Inicio fresco
El estándar de medición que consume más tiempo
- Arranque en caliente
lo más rápido. Entre bastidores ~ Frente al escenario
- Arranque en caliente
Más rápido. Sólo repetirá el ciclo de vida de la actividad, pero no la creación del proceso y el ciclo de creación y vida de la Aplicación.
proceso de arranque en frio
- Clics del usuario
- Activar operación IPC
- Creación del proceso Process.start
- ActivityThread es la entrada a cada proceso por separado. Habrá un método principal para crear el bucle de mensajes y el controlador.
- bindApplication crea una aplicación a través de la reflexión y llama al ciclo de vida de la aplicación.
- Ciclo de vida de la actividad Ciclo de vida
- ViewRootImpl inicia el dibujo de la interfaz real
Antes del arranque en frío (este proceso no se puede intervenir)
- Iniciar aplicación
- Cargar una ventana en blanco
- Proceso de creación
Tareas posteriores
- Crear aplicación
- Iniciar el hilo principal
- Crear actividad principal
- Cargar diseño
- pantalla de diseño
- Primer cuadro dibujado
Optimice
el ciclo de vida de la Aplicación y la Actividad
2. Cómo medir el tiempo de inicio
modo de comando adb
adb shell am start -W nombre del paquete/首屏Actividad
Características:
- Fácil de usar sin conexión pero no se puede conectar a Internet
- Tiempo no estricto y preciso
El método de marcado manual
entierra puntos cuando comienza y entierra puntos cuando comienza y termina. La diferencia entre las dos
características:Preciso, se puede poner en línea, se recomienda su uso
Evite malentendidos
- El punto de inicio del tiempo de inicio está en el adjuntoBaseContext de la aplicación.
- La posición final del tiempo de inicio adopta la primera visualización del avance.
- addOnDrawListener requiere API 16
ThisTime El tiempo necesario para iniciar la última actividad
TotalTime El tiempo necesario para iniciar todas las actividades
WaitTime El tiempo total necesario para iniciar la actividad AMS
3. Inicie las herramientas utilizadas para la optimización.
vista de seguimiento, ruta del sistema
- Ambas herramientas se complementan
- Comprender correctamente las herramientas y elegir las herramientas adecuadas para diferentes escenarios.
vista de seguimiento
- ventaja
- Forma gráfica, que muestra el tiempo de ejecución del código, información de la pila de llamadas, etc.
- Información completa, incluida toda la información del hilo.
- Uso
Debug.startMethodTracing("nombre de archivo"); el tamaño predeterminado es 8M. Si desea un tamaño mayor, pase el parámetro bufferSize.
Debug.stopMethodTracing()
generará un archivo al final de la tarjeta SD: Android/data/packagename /archivos
Hay un Explorador de archivos de dispositivos en el lado derecho de Android Studio, que puede abrir fácilmente los archivos del sistema del teléfono móvil.
Después de agregar el código de apertura y cierre, ejecútelo, actualícelo en la ubicación de almacenamiento y establezca un nombre de archivo. Se generará el archivo .trace.
- como analizar
-
- La parte superior izquierda es el rango de tiempo especificado con precisión a través del código, y hay un tiempo en la esquina inferior izquierda, que no es particularmente importante.
- La parte inferior izquierda es la información del hilo. Puede ver el número total de hilos y lo que hizo cada hilo en un momento específico.
Hay cuatro pestañas a la derecha.
- De arriba hacia abajo
total: tiempo total
ser :
niños:
Por ejemplo: se llama a la función A, el tiempo total es total, se llama a una línea de código en la función A y luego se ejecuta la función B. Su selfTime es el momento en que se ejecuta una línea de código y ChildrenTime es el momento en que Se ejecuta la función B. La suma de selfTime y childTime debe ser igual a totalTime.
Lista de llamadas de función, haga clic en el salto correspondiente a souse para saltar al código detallado
ThreadTime definitivamente disminuirá, el momento en que la CPU ejecuta
Wall Clock Time El código ocurre en este hilo, el tiempo de ejecución real
- chat de llamada
Cada fila muestra el período de tiempo de la llamada a la función y se llama al método vertical.
El color de la llamada a la API del sistema es naranja,
la llamada a la función propia de la aplicación es verde y
la llamada a la API de terceros es azul.
- Gráfico de llamas de chat de llamas
Gráfico de llamadas invertidas, que recoge la misma secuencia de llamadas
- De abajo hacia arriba
Quien me llamó es lo opuesto a De arriba hacia abajo
Resumen:
La sobrecarga del tiempo de ejecución es grave y todo se ralentizará. Esta herramienta es demasiado poderosa y capturará todas las funciones de ejecución de todos los subprocesos y el orden puede
sesgar la dirección de optimización. Los beneficios de
traceview y cpu Profiler
traceview pueden ser enterrado en el código Utilice el análisis del perfilador de CPU
Es casi imposible usar simplemente el perfilador de CPU para capturar la ubicación de inicio precisa.
sistematrace
Combine datos del kernel de Android para generar
un script Python de informe html
- Uso
• python systrace.py -t 10 [otras opciones] [categorías]
- Documentación oficial:
https://developer.android.com/studio/command-line/systrace#command_options
- Casos de uso
python /Users/Liuzhao.Future/Library/Android/sdk/platform-tools/ systrace/systrace.py -b 32768 -t 5 -a com.optimize.rendimiento -o rendimiento. aplicación html programada gf view wm am
- utilizado en el código
Abierto: TraceCompat.beginSection(“apponCreate”)
Fin: TraceCompat.endSection
- Analizar archivos html
La cantidad de núcleos de CPU está relacionada con diferentes teléfonos móviles. Algunos fabricantes de teléfonos móviles le ofrecen 8 núcleos. Algunos teléfonos móviles tienen 8 núcleos, pero solo se utilizan 4 núcleos.
- Resumir:
- Ligero, con pocos gastos generales, simplemente haz lo que quieras
- Refleja intuitivamente la utilización de la CPU
cpuTime y wallTime
- wallTime es el momento en que se ejecuta el código
- cpuTime es el tiempo que el código consume la CPU (indicador clave)
Ejemplo: ¿Por qué los dos tienen diferentes
conflictos de bloqueo? Por ejemplo, un subproceso necesita adquirir el bloqueo A para su ejecución, pero el bloqueo A está retenido por otros subprocesos y no se ha liberado. Sin embargo, este subproceso es liviano y solo ocupa un poco tiempo de la CPU, por lo que en este momento cpuTime será muy corto y wallTime será muy largo.
4. Cómo obtener elegantemente el consumo de tiempo de CPU
Necesita saber qué método está consumiendo más tiempo
- Método convencional: puntos de enterramiento manuales
- muy invasivo
- Pesada carga de trabajo
- Método AOP: programación orientada a aspectos, programación orientada a aspectos
- Manejo unificado del mismo tipo de problemas.
- Agregar código sin intrusión
Uso de aspectos
- classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
- implementación 'org.aspectjaspectjrt:1.8.+'
- aplicar complemento: 'android-aspectix'
introducir
- Unirse a puntos
- El punto de ejecución cuando el programa se está ejecutando se puede utilizar como lugar para aspectos
- llamada de función, ejecución
- Obtener y establecer variables
- Inicialización de clase
- Punto de corte
- JoinPoints con condiciones
- Consejo
- Una especie de gancho, donde se insertará el código.
- Antes: ejecutado antes de PointCut
- Después: ejecutado después de PointCut
- Alrededor: ejecutar por separado antes y después de Pointcut
- Introducción a la gramática
//Before:Advice,具体插入位置 //execution :处理Join Point的类型 //(* android.app.Activity.on**(.)):匹配规则 @Before("execution(* android.app.Activity.on** (.))") public void onActivityCalled (JoinPoint joinPoint) thr ows Throwable { …… }
- Casos de uso
@Aspect public class Performanceaop{ Around("call(*com.optimize.performance.PerformanceApp.**(..))") public void getTime(ProceedingJoinPointjoinPoint){ Signature signature=joinPoint.getSignature(); String name=signaturetoShortString(); long time=System.currentTimeMillis(); try { joinPoint.proceed(); } catch(Throwable throwable){ throwable.printStackTrace(); } LogUtils.i(msg:name+" cost "+(System.currentTimeMillis() - time)); } }
- ventaja
- No invasivo
- Fácil de modificar
5. Optimización asincrónica
- Optimización asincrónica general: uso de grupos de subprocesos para optimización asincrónica
- Launcher (la solución óptima para la optimización del inicio asíncrono)
Modo asíncrono normal
Cosas a tener en cuenta sobre los métodos asincrónicos convencionales:
- No todo el código puede ser directamente asincrónico
- No cumple con los requisitos asincrónicos: algunas tareas deben ejecutarse en el hilo principal
- Debe completarse en una etapa determinada. Las tareas asincrónicas se utilizan en la interfaz de presentación. Al ejecutar la interfaz, algunos códigos deben completarse en una etapa determinada antes de que se complete la tarea asincrónica. Solución: CountDownLatch es equivalente a agregar un candado.
- Distinguir entre tareas con uso intensivo de CPU y tareas con uso intensivo de IO
Puntos débiles de las soluciones asincrónicas convencionales:
- El código no es lo suficientemente elegante.
- La escena es difícil de manejar (dependencia), finalice una tarea dentro de un tiempo específico
- Altos costos de mantenimiento
Modo lanzador
Idea central:
aprovechar al máximo los múltiples núcleos de la CPU y ordenar automáticamente la secuencia de tareas.Proceso
de inicio:
- El código está orientado a tareas y la lógica de inicio se abstrae en Tarea.
- Genere un gráfico acíclico dirigido basado en las dependencias de todas las tareas.
- Los subprocesos múltiples se ejecutan secuencialmente según la prioridad ordenada.
6. Inicialización retrasada
- Solución general: handler.postDelay
- Mejor solución: inicializar las tareas retrasadas en lotes
Problemas con las soluciones convencionales:
- El momento es difícil de controlar.
- Causando retraso en la alimentación
Ventajas de la mejor solución: aprovechando la función IdleHandler, ejecución inactiva
- El tiempo de ejecución es claro.
- Aliviar el retraso en la alimentación
7. Resumen: poner en marcha la política general de optimización
- Carga asíncrona, retrasada y diferida
- Combinando tecnología y negocios
8. Precauciones
- Permisos de modificación del código de inicio de convergencia
- La modificación del código de inicio junto con Ci requiere una revisión o notificación
9. Otras opciones
- Cargue SharedPreferences con anticipación
Cargue antes de multidex, aproveche al máximo esta etapa y la CPU
sobrescribirá getApplicationContext y devolverá esto
- No inicie procesos secundarios durante el inicio
Los procesos secundarios compartirán recursos de la CPU, lo que provocará que la CPU del proceso principal se esfuerce.
Preste atención a la secuencia de inicio. La aplicación onCreate está precedida por ContentProvider.
- Optimización de la carga de clases, carga de clases asincrónica por adelantado
- Suprimir GC durante la fase de inicio
- Bloqueo de frecuencia de la CPU