Red de conocimiento informático - Consumibles informáticos - ¿Cuál es el objetivo de la optimización del rendimiento de Android?

¿Cuál es el objetivo de la optimización del rendimiento de Android?

1. Resumen:

Este artículo analiza principalmente la optimización del rendimiento de Android desde los aspectos del mecanismo de renderizado, optimización de la interfaz de usuario, procesamiento multiproceso, procesamiento de caché, optimización del consumo de energía, especificaciones de código, etc.

2. Optimización del mecanismo de renderizado:

La mayoría de los usuarios creen que la principal fuente de problemas de rendimiento, como el bloqueo, es el rendimiento del renderizado.

El sistema Android envía una señal VSYNC cada 16 ms para activar la representación de la interfaz de usuario. Si cada renderizado tiene éxito, se pueden lograr los 60 fps necesarios para una imagen fluida. Para lograr 60 fps, esto significa que la mayoría de las operaciones del programa deben completarse en 16 ms.

Si una de sus operaciones tarda 24 ms y el sistema no puede procesarse normalmente cuando recibe la señal VSYNC, entonces Se producirán caídas de fotogramas. Entonces el usuario verá el mismo fotograma en 32 ms

Probablemente: tal vez porque su diseño es demasiado complejo para renderizarlo en 16 ms, tal vez porque hay demasiadas unidades de dibujo en su interfaz de usuario, o tal vez porque la animación es ejecutado demasiadas veces. Esto hará que la CPU o GPU se sobrecargue.

Resuelto: Podemos utilizar algunas herramientas para localizar el problema. Por ejemplo, podemos usar HierarchyViewer para descubrir si el diseño de la actividad es demasiado complejo, o podemos usar las opciones de desarrollador en la configuración del teléfono para activar opciones como mostrar GPU Overdraw para observar.

También puedes utilizar TraceView para observar la ejecución de la CPU y encontrar cuellos de botella en el rendimiento más rápidamente.

SobreDibujar;

SobreDibujar describe que un píxel en la pantalla se dibuja varias veces en el mismo cuadro. En una estructura de interfaz de usuario de varios niveles, si también se dibuja la interfaz de usuario invisible, esto provocará que algunas áreas de píxeles se dibujen varias veces. Esto desperdicia muchos recursos de CPU y GPU. ?

Recordatorio: podemos activar la opción para mostrar el sobregiro de GPU a través de las opciones de desarrollador en la configuración del teléfono móvil y observar la situación del sobregiro en la interfaz de usuario.

Ilustración: Azul, verde claro, rojo claro y rojo oscuro representan cuatro grados diferentes de sobregiro. El objetivo es minimizar el exceso de rojo y ver más áreas azules.

Recordatorio: el sobregiro a veces se debe a una gran cantidad de partes superpuestas en el diseño de la interfaz de usuario y, a veces, a fondos superpuestos innecesarios. Por ejemplo, una actividad tiene un fondo, luego el diseño dentro de ella tiene su propio fondo y las subvistas tienen su propio fondo.

Simplemente eliminando imágenes de fondo innecesarias, puedes reducir la cantidad de áreas rojas sobredibujadas y aumentar la proporción de áreas azules. Esta medida puede mejorar significativamente el desempeño del programa.

Nota: Para obtener más información sobre el mecanismo de renderizado, ¿muévete? /introducción-de-webp.html

6. Optimización de energía:

Existen algunas medidas que pueden reducir significativamente el consumo de energía:

Minimizar el número de veces. activa la pantalla y la duración, usa WakeLock para manejar los problemas de activación, realiza las operaciones de activación correctamente y cierra las operaciones de manera oportuna para ingresar al estado de suspensión de acuerdo con la configuración.

Algunas operaciones que no es necesario realizar inmediatamente, como cargar canciones y procesar imágenes, solo se pueden realizar cuando el dispositivo se está cargando o la batería está llena.

La operación que activa la solicitud de red mantendrá la señal inalámbrica durante un período de tiempo cada vez. Podemos agrupar solicitudes de red dispersas en una sola operación para evitar el consumo de energía causado por señales inalámbricas excesivas.

Para conocer el consumo de energía de las señales inalámbricas causado por solicitudes de red, también puede consultar work-access.html aquí.

Pregunta: Supongamos que tiene una gran cantidad de aplicaciones sociales instaladas en su teléfono. Incluso si su teléfono está en modo de espera, estas aplicaciones a menudo lo activarán para verificar y sincronizar nueva información de datos.

Android seguirá apagando varios hardware para extender el tiempo de espera del teléfono. Primero, la pantalla se atenuará gradualmente hasta que se apague y luego la CPU entrará en modo de suspensión. Todas estas operaciones se realizan para ahorrar valiosos recursos energéticos. Pero incluso en este estado de suspensión, la mayoría de las personas siguen trabajando duro y siguen activando sus teléfonos.

Una de las formas más sencillas de reactivar el teléfono es utilizar la API de PowerManager. Wake Lock mantiene la CPU funcionando y evita que la pantalla se atenúe y se apague.

Esto permite que el teléfono se despierte, realice un trabajo y luego vuelva a dormir. Saber cómo obtener un WakeLock es sencillo, pero también es importante liberar el WakeLock a tiempo.

El uso inadecuado de wake locks puede provocar errores graves. Por ejemplo, el tiempo de retorno de datos requerido por la red es incierto, lo que hace que cosas que originalmente solo requerían 10 esperen una hora, lo que desperdiciará energía. Por eso es fundamental utilizar el método wakelock.acquice() con un parámetro de tiempo de espera.

Pero simplemente establecer un tiempo de espera no es suficiente para resolver el problema. Por ejemplo, ¿cuál es la proporción de tiempo de espera adecuada? ¿Cuándo volver a intentarlo, etc.?

Resuelto: La forma correcta de resolver el problema anterior puede ser utilizar un temporizador inexacto. Normalmente, estableceríamos un tiempo para una operación, pero podría ser mejor modificar este tiempo dinámicamente.

Por ejemplo, si hay otro programa que necesita despertarse 5 minutos más tarde de la hora que configuraste, lo mejor es esperar hasta esa hora y las dos tareas se agrupan y se realizan al mismo tiempo. . Este es el principio de funcionamiento básico de los temporizadores imprecisos. Podemos personalizar las tareas programadas, pero si el sistema detecta un mejor horario, puede posponer tus tareas para ahorrar energía.

*? ¿Puedes consultar más conocimientos sobre JobScheduler? http://Hu kai .me/Android-training-course-in-Chinese/background-jobs/scheduling/index html

Especificaciones del código

1) No. Declare variables temporales en un bucle for y no escriba try catch en él a menos que sea absolutamente necesario.

2) Comprenda el mecanismo de recolección de basura y evite GC frecuentes, pérdidas de memoria y OOM (específicamente cuando haya una oportunidad).

3) Uso razonable de tipos de datos, StringBuilder en lugar de String, menos enumeración, menos declaración de clase principal (Lista, Mapa).

4) Si hay subprocesos nuevos con frecuencia, es mejor ejecutarlos a través del grupo de subprocesos para reducir la sobrecarga de la creación de subprocesos.

5) Es necesario conocer los beneficios del singleton y utilizarlo correctamente.

6) Utilice más constantes, "action_key" menos explícita y mantenga una clase constante. No declare estas constantes repetidamente.

7) Si es posible, al menos comprenda el modo estrategia, el modo combinación, el modo decorador, el modo fábrica y el modo observador en los patrones de diseño, lo que puede ayudarlo a comprender el desacoplamiento de manera razonable. Incluso si tus necesidades cambian con frecuencia, no temas que un solo movimiento afecte a todo el cuerpo. Los cambios en los requisitos no dan miedo. Lo que da miedo es que no existe un diseño razonable antes de escribir el código.

8) Establezca las propiedades de la caché en la 8) vista. setDrawingCache es verdadero.

9) ¿Cursor? de uso. Pero tenga cuidado al administrar el cursor y no lo encienda y apague cada vez, porque encenderlo y apagarlo lleva mucho tiempo. Cursor.require se utiliza para cepillar el cursor.

10) Utilice SurfaceView para actualizar la interfaz de usuario en el hilo secundario. Evite manipular y dibujar gestos en el mismo hilo de la interfaz de usuario (las vistas normales hacen esto).

11) Utilice JNI para colocar el procesamiento que requiere mucho tiempo en la capa c/c++.

12) Algunas personas que saben cómo utilizar operaciones de archivos intentan utilizar operaciones de archivos. Las operaciones con archivos son aproximadamente 10 veces más rápidas que las operaciones con bases de datos.

13) Mecanismo de carga diferida y almacenamiento en caché. Las operaciones de acceso a la red que requieren mucho tiempo iniciarán un nuevo hilo para completar, en lugar de un hilo de UI.

14) Si el método no utiliza variables miembro, se puede declarar estático y el rendimiento mejorará entre un 15% y un 20%.

15) Evite el uso de getters/setters para acceder al campo. Puedes declarar el campo como público y acceder a él directamente.

16) Cuando una clase interna privada quiere acceder a campos o métodos de una clase externa, sus variables miembro no deben ser privadas, porque los setters/getters se generarán en el momento de la compilación, lo que afectará el rendimiento. Puede declarar un campo o método de una clase externa como paquete accesible.

17) El uso adecuado de los números de coma flotante es dos veces más lento que el de los números enteros.

18) Para optimizar el rendimiento de ListView, el color de fondo de ListView es el mismo que el de cacheColorHint, lo que puede mejorar el rendimiento de renderizado al deslizar. GetView en ListView es la clave del rendimiento, por lo que debe optimizarse tanto como sea posible.

View; debe reutilizarse en el método getView; no se pueden realizar cálculos lógicos complejos en el método getView, especialmente operaciones de base de datos, de lo contrario, el rendimiento se verá seriamente afectado al deslizarse.

19) Crea una instancia de una clase sin la nueva palabra clave. Cuando crea una instancia de una clase usando la nueva palabra clave, todos los constructores en la cadena de constructores se llaman automáticamente. Pero si un objeto implementa la interfaz Cloneable, podemos llamar a su método clone().

El método clone() no llama a ningún constructor de clase. Cuando se utilizan patrones de diseño, si utiliza el patrón de fábrica para crear objetos, es muy sencillo crear nuevas instancias de objetos utilizando el método clone(). Por ejemplo, la siguiente es una implementación típica del patrón de fábrica:

20) Crédito estático público getNewCredit() {

Devolver nuevo crédito();

}

El código mejorado utiliza el método clone(), como se muestra a continuación:

Crédito base de crédito estático privado = crédito nuevo();

Crédito estático público getNewCredit() {

return(Credit)base Credit . clone();

}

Las ideas anteriores también son útiles para el procesamiento de matrices.

21) Multiplicación y división

Considera el siguiente código:

for(val = 0; val & lt100000; val+= 5){ alterX = val * 8 ;mi resultado = val * 2;}

Usar operaciones de desplazamiento en lugar de operaciones de multiplicación puede mejorar enormemente el rendimiento. El siguiente es el código modificado:

for(val = 0; val & lt100000;val+= 5){ alterX = val & lt;& lt3;myResult = val & lt& lt1;}

22) El número de páginas almacenadas en caché por Viewpage al mismo tiempo debe ser al menos 3. Si hay demasiados, habrá mucha inicialización del buscapersonas cuando el Viewpager se muestre por primera vez, por lo que el tiempo de representación acumulativo del buscapersonas aumentará y se verá muy atascado.

23) Cada buscapersonas solo debe cargar la red o la base de datos (UserVisibleHint=true) cuando se muestra. Es mejor no precargar datos para evitar el desperdicio.

24) Mejore la velocidad de descarga: controle el número máximo de tareas de descarga simultáneas más rápido y, al mismo tiempo, encapsule una capa de flujo almacenado en búfer (como BufferedInputStream) para InputStream.

25) Proporcionar velocidad de carga: La mejor solución es dejar que el servidor proporcione imágenes de diferentes resoluciones. También existe el uso racional de la memoria caché y los marcos de código abierto.

Introducción: Acerca de la optimización del rendimiento de Android