Red de conocimientos turísticos - Conocimientos sobre calendario chino - ¿Cuáles son algunos buenos métodos de optimización de la memoria en el desarrollo de Android?

¿Cuáles son algunos buenos métodos de optimización de la memoria en el desarrollo de Android?

Optimización de memoria

Codificación

Mapa de bits

ListView

SoftReference y WeakReference

UI

2.1 Codificación

Consejo 1: Utilice contenedores de datos optimizados.

Por ejemplo, SparseArray, SparseBooleanArray, LongSparseArray, no HashMap

Requisito previo: el tipo de clave es entero

Razón:

HashMap memoria No es suficiente porque cada asignación requiere una entrada separada (como se muestra a continuación).

Cada elemento ocupa 8 bytes más de memoria (dos variables miembro más, next y hash). La conversión de AutoBoxint a Integer crea otro objeto, que también ocupa 4 bytes más de memoria.

HashMap es menos eficiente en memoria porque cada mapeo requiere una entrada separada (como se muestra en la figura siguiente).

SparseArray utiliza un método de búsqueda binaria, que es ligeramente menos eficiente que HashMap, pero la diferencia de rendimiento no es significativa dentro de cientos de órdenes de magnitud.

HashMap hashMap = nuevo HashMap();

Reemplazar

SparseArray sparseArray = nuevo SparseArray();,

Consejo 2: Utilice IntentService en lugar de Service.

Ventajas de IntentService: abre un nuevo hilo; procesa los intentos en secuencia; sale automáticamente una vez completado.

Nota:

El servicio es un servicio sin interfaz, pero en realidad no es un servicio en segundo plano. Todo el código se ejecuta en el hilo de la interfaz de usuario de forma predeterminada.

IntentService hereda de Service, por lo que también es un servicio.

IntentService utiliza una cola para agregar Intents solicitados a la cola y luego abre un hilo de trabajo para manejar los Intents en la cola. Para una solicitud startService asincrónica, IntentService manejará la primera solicitud antes de manejar la segunda solicitud. Cada solicitud se maneja en un subproceso de trabajo independiente y no bloquea el subproceso principal de la aplicación.

La diferencia entre IntentService y Service:

1. El servicio se ejecuta en el subproceso de la interfaz de usuario de forma predeterminada, mientras que el método onHandleIntent de IntentService se ejecuta en segundo plano.

2. Una vez iniciado el Servicio, siempre existirá si no se detiene manualmente y IntentService se cerrará automáticamente después de la ejecución.

Consejo 3: Intenta evitar el uso de enumeraciones.

Las enumeraciones requieren el doble o más de memoria que las constantes estáticas. Aquí está la definición de tipo para Enum:

Consejo 4: utilice un ofuscador para eliminar código innecesario.

La herramienta ProGuard comprime, optimiza y ofusca el código eliminando el código inactivo y utilizando la ofuscación semántica para preservar clases, campos y métodos. Reduce las páginas asignadas en RAM y hace que el código sea más completo.

Consejo 5: Intenta no utilizar bibliotecas enormes para solo una o dos funciones.

Consejo 6: utilice StringBuffer (seguro para subprocesos) o StringBuilder (no seguro para subprocesos) para modificaciones frecuentes.

Cuando se utiliza String para modificar una cadena, si la cadena modificada no existe en el área constante de cadena, se creará un nuevo objeto String.

Consejo 7: Para constantes, utilice static final siempre que sea posible.

Si usa final para definir constantes, el compilador reducirá el almacenamiento al inicializar la clase y llamar al método durante la generación de la clase. Para las constantes int, el valor se sustituirá directamente, mientras que para los objetos String se utilizará un método relativamente económico. Los objetos utilizarán la relativamente barata directiva "constante de cadena" para reemplazar la tabla de búsqueda de campos. Si bien este enfoque no funciona para todos los tipos, definitivamente es una buena práctica declarar las constantes como estáticas finales.

Consejo 8: Es mejor anular explícitamente el objeto cuando no lo use

Es mejor anular explícitamente el objeto cuando no lo use para reducir la sobrecarga de GC.

Advertencia: las variables estáticas pueden causar pérdidas de memoria

Hay un objeto de recurso estático en este código. El fragmento de código mResources = this.getResources() inicializa el objeto Recursos. En este punto, el objeto de recurso tiene una referencia al objeto activo actual, y el objeto activo actual tiene referencias a todos los objetos en toda la página.

Si recrea la Actividad actual (por ejemplo, cambiando entre pantallas horizontales y verticales, se recreará toda la Actividad de forma predeterminada), dado que Recursos se refiere a la primera Actividad creada, esto dará como resultado la primera Actividad. El recolector de basura no puede reciclar la primera actividad creada, lo que hace que todos los objetos de la primera actividad creada no puedan reciclarse. En este punto, se desperdicia algo de memoria.

Advertencia: El uso de un contexto de actividad puede provocar una pérdida de memoria.

Se debe utilizar el contexto de la aplicación tanto como sea posible.

En Android, el ciclo de vida de un contexto de aplicación es tan largo como el ciclo de vida de la aplicación y no depende del ciclo de vida de una Actividad específica. Si desea conservar un objeto con una vida útil prolongada y ese objeto requiere un contexto, puede utilizar un objeto de aplicación.

Preste atención a si el ciclo utilizado está dentro del ciclo activo. Si excede el ciclo activo, debe usar la aplicación; los escenarios de aplicación comunes incluyen AsyncTask, Thread, inicialización de bibliotecas de terceros, etc.

También hay algunos escenarios de aplicaciones que solo pueden usar actividades: por ejemplo, cuadros de diálogo, varias vistas que necesitan iniciar actividades, etc. De todos modos, debes utilizar la aplicación siempre que sea posible.

La pérdida de memoria causada por las variables estáticas anteriores se puede modificar de la siguiente manera:

2.2 Mapa de bits

Consejo: detectar excepción

Debido a Bitmap Es un gran consumidor de memoria. Para evitar que la aplicación asigne memoria de Bitmap cuando ocurre una excepción OutOfMemory, debe prestar especial atención al código que crea una instancia de Bitmap. Normalmente, las excepciones OutOfMemory deben quedar atrapadas en el código que crea una instancia del mapa de bits.

OutOfMemoryError es un error, no una excepción: almacenar en caché imágenes genéricas, este método no funciona

Escenario de aplicación: avatar predeterminado. En ocasiones, es posible que necesites utilizar la misma imagen varias veces en una campaña. Por ejemplo, una actividad muestra una lista de avatares de usuarios y, si el usuario no ha configurado un avatar, muestra el avatar predeterminado, que se encuentra en el archivo de recursos de la propia aplicación.

¡Este método no funcionará! Porque:

Porque Android tiene su propio mecanismo de almacenamiento en caché de archivos de recursos:

En la clase Resource.java, existe LongSparseArray > mDrawableCache

Drawable se creará uno a la vez, pero el mapa de bits interno seguirá apuntando al mapa de bits en el caché.

Consejo: comprimir imágenes

BitmapFactory.Options opciones = new BitmapFactory.Options();

options.inSampleSize = 2;

Si los píxeles de la imagen son demasiado grandes al crear una instancia de un mapa de bits utilizando métodos de la clase BitmapFactory, se producirá una excepción OutOfMemory.

El tamaño de la imagen se puede reducir configurando inSampleSize usando BitmapFactory. El valor del atributo inSampleSize indica que el tamaño de la miniatura es una fracción del tamaño de la imagen original. Es decir, si el valor es 2, el ancho y el alto de la miniatura serán la mitad del tamaño de la imagen original y la imagen tendrá 1/4 del tamaño de la imagen original.

Si sabes que los píxeles de una imagen son demasiado grandes, puedes reducirlos. Entonces, ¿cómo saber si una imagen es demasiado grande?

Usar BitmapFactory.Options para establecer inJustDecodeBounds en verdadero y luego usar métodos como decodeFile() en realidad no puede asignar espacio, es decir, el mapa de bits decodificado está vacío, pero el ancho y alto de la imagen original pueden calcularse, es decir, las opciones options.outWidth y options.outPlus.outPlus.outWidth. Con estos dos valores podrás saber si la imagen es demasiado grande.

Primero obtenga el ancho y alto reales de la imagen, luego determine si necesita ejecutar la reducción. Si no se requiere reducción, el valor de inSampleSize se establece en 1; si se requiere reducción, el valor de inSampleSize se calcula dinámicamente y se establece para reducir la imagen.

Consejo: Recicle la memoria Bitmap a tiempo (≤Android 2.3.3, API10)

El método constructor de la clase Bitmap es privado, por lo que los desarrolladores no pueden crear directamente un nuevo objeto Bitmap. pero solo puedes usar varios métodos estáticos de la clase BitmapFactory para crear una instancia de un objeto Bitmap

Si observas de cerca el código fuente de BitmapFactory, puedes encontrar que la generación de objetos Bitmap se implementa finalmente a través de llamadas JNI. . Por lo tanto, una vez cargado el mapa de bits en la memoria, contiene dos partes del área de memoria. En pocas palabras, es parte Java y parte C. Java asigna parcialmente el objeto Bitmap y el sistema lo reciclará automáticamente cuando no esté en uso. Sin embargo, la máquina virtual no puede reciclar directamente el área de memoria disponible de C correspondiente. En este momento, solo se puede llamar a la función subyacente. suéltalo. Por lo tanto, es necesario llamar al método de reciclaje () para liberar la parte C de la memoria. En el código fuente de la clase Bitmap, también puede ver que el método recycle() llama a un método JNI.

2.3 ListView

Consejo: obtenga la vista en caché de ContentView

Si no utiliza el caché convertView, la vista se debe volver a crear cada vez que se ejecuta getView. llamado, por lo que antes Es posible que la vista aún no se haya destruido, y la creación constante de nuevas vistas conducirá inevitablemente a pérdidas de memoria. Esto provocará una pérdida de memoria.

Consejo: utilice el patrón ViewHolder para evitar llamadas innecesarias a findViewById()

El patrón ViewHolder almacena una estructura de datos en el marcado de la vista devuelta por el método getView(), que contiene nuestra referencia A a la vista a la que se vincularán los datos. Esto evita llamar a findViewById() cada vez que se llama a getView().

2.4 SoftReference y WeakReference

SoftReference

La memoria de estos objetos solo se recupera cuando no hay suficiente espacio de memoria.

Se pueden utilizar referencias suaves para implementar el almacenamiento en caché sensible a la memoria.

Map> imageCache = new HashMap>();

Referencia débil

En recolección de basura Reciclado durante el análisis del dispositivo.

Map> cacheMap = new HashMap>();

Solo los objetos de referencia débiles tienen un ciclo de vida más corto. Una vez que el hilo del recolector de basura escanea el área de memoria bajo su jurisdicción y encuentra un objeto con solo referencias débiles, recuperará su memoria independientemente de si hay suficiente espacio en la memoria actual. Sin embargo, dado que el recolector de basura es un subproceso de baja prioridad, es posible que no siempre encuentre rápidamente objetos que solo tienen referencias débiles.

Caso: carga asincrónica de imágenes de red

Consulte: /a/anzhuokaifa/androidkaifa/2013/0920/1554.html

2.5 Interfaz de usuario

Consejo 1: Utilice los recursos del sistema

Identificación definida por el sistema: por ejemplo @android. Por ejemplo @*android:drawable/ic_menu_attachment

Recurso de cadena de texto del sistema: por ejemplo @android :string/yes

Estilo del sistema: por ejemplo android: textAppearance = "?android:attr/textAppearanceMedium"

Definición de color del sistema: por ejemplo, android:background = "@android:color /transparent"

Descripción:

El sistema Android en sí tiene una gran cantidad de recursos, incluidas varias cadenas, imágenes, animaciones, estilos, diseños, etc. que se puede utilizar directamente en las aplicaciones. Esto tiene muchos beneficios, incluida la reducción del uso de memoria, el alivio de parte de la carga de trabajo y la reducción del tamaño del paquete de instalación del programa.

No hay recursos disponibles públicamente en Android y hacer referencia a ellos directamente en xml generará errores. Además de buscar el recurso correspondiente y copiarlo en nuestro propio directorio de aplicaciones, también podemos cambiar la referencia de "@android" a "@*android" para solucionar el problema.

Consejo 2: Extracción normal del módulo

Fondo

Barra de título del encabezado

Barra de navegación inferior

ListView

Consejo 3.: ViewStub

ViewStub es un objeto de vista oculto y sin memoria que puede retrasar la carga de Diseñar archivos de recursos en tiempo de ejecución.

>