2011-04-07 10 views
9

Tengo una lista que muestra miniaturas (imágenes pequeñas) descargadas sobre la marcha desde la Web. En algún punto, el proceso se queda sin memoria. ¿Cómo puedo saber que la memoria libre está a punto de agotarse, así que puedo dejar de descargar más imágenes?Prevención de falta de memoria en Android

Me gustaría saberlo de antemano para no estar al borde de la falta de memoria.

Nota: No es una pérdida de memoria, solo muchos mapas de bits descargados.

Gracias.

+0

Elaboraré un poco más. Para no descargar cada imagen varias veces, almaceno las imágenes descargadas en la actividad y reemplazo las imágenes viejas - LRU. Me gustaría saber cuándo detener el almacenamiento en caché o vincular el tamaño del LRU. –

+0

Tengo el mismo problema, probé las referencias de software y lo que sea ... –

Respuesta

3

Uso SoftReference para contener los objetos de mapa de bits. La lista solo necesita las imágenes visibles actuales. Por lo tanto, nunca tengo que preocuparme por quedarme sin espacio.

El inconveniente es que cuando veo las imágenes, desplazarse hacia abajo (haciendo que algunos SoftReferences para borrar los mapas de bits), y vaya de nuevo al mismo lugar - las imágenes se descargan de nuevo :(

Además, los SoftReferences se borrará muy rápido. Esperaría que guarden el mapa de bits interno por más tiempo.

+0

Muy similar a la respuesta: http://stackoverflow.com/questions/1945201/android-image-cache/1945518#1945518 –

+0

Hoy en día, use LruCache en lugar de SoftReferences. Para evitar el problema que está teniendo, las referencias se borran de forma más agresiva de lo que espera. http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html – ToolmakerSteve

-1

Puede pasar por encima de método de la Actividad onLowMemory() para la dirección de encargo tales escenarios

+0

Me gustaría no llegar a ese punto y definir algo como: Deje de golpear la memoria caché si la memoria utilizada alcanzó el 80% –

+3

No tengo este método llamado, solo recibe la excepción OOM. –

+0

onLowMemory() no llamado antes OOM –

2

Debe utilizar inSampleSize opción de BitmapFactory.Options durante la creación de los mapas de bits.

Además, algunos de los consejos en Android: out of memory exception in Gallery me han sido útiles para controlar la memoria disponible.

+0

Independientemente del tamaño, si tengo demasiadas imágenes, con el tiempo, el proceso se queda sin memoria. –

+0

Por supuesto. Y, en última instancia, debe detenerse en un número finito de imágenes. La pregunta realmente debería ser cómo impulsar este límite tanto como sea aceptablemente posible. – rajath

27

1) Tienes que ser tu propio navegador.

Descargue sus pulgares a la tarjeta SD en lugar de guardarlos en la memoria RAM. Reduzca/gírelos antes de guardarlos para que la próxima vez que los cargue, la carga sea "gratuita" desde la tarjeta SD en lugar de costosa desde los internets. (Es decir: como cualquier navegador, use un caché de archivos local).

Libere cualquier objeto Bitmap provisional que pueda crear para hacer esto.

Aprenda a usar el parámetro "inSampleSize" para descomprimir Bitmaps a menos que la resolución original.

Si los archivos que escribe finalizan en una extensión de imagen (.jpg, etc.) aparecerán en la Galería, por lo que no guarde sus pulgares con nombres de archivo de imagen obvios.

2) Cree un sistema de caché en niveles (Mapa de bits> Tarjeta SD> Internets).

Al desempacar una miniatura, guárdela en una memoria caché de SoftReference. Si necesita usar esa miniatura, solicítela desde el caché. Si la VM necesita más memoria, su instancia de SoftReference puede devolver nulo.

Si obtiene nulo de su caché de mapa de bits, entonces verifique si ya ha puesto su url en la tarjeta SD y colóquela en el caché de mapa de bits desde allí.

Si obtienes nulo de tu sistema de archivos, entonces ve a descargar la imagen de internet y guárdala en tu tarjeta SD y pégala en tu caché de mapa de bits.

3) Liberar recursos que no se están utilizando.

De la misma manera, asegúrese de borrar los mapas de bits de las vistas en las que se han colocado tan pronto como la vista esté fuera de pantalla (si sus vistas viven en un ListView u otro elemento adaptado, esto es esencialmente "gratuito"). "desde el reciclaje de los elementos de la Vista) - Sin embargo, si tiene ImageViews instanciado con mapas de bits y no se muestran inmediatamente en la pantalla, probablemente esté desperdiciando mucho.

Puede simplemente llamar al setImageBitmap(null); en una ImageView y la referencia al mapa de bits se eliminará (de modo que si la única referencia es SoftReference cuando no se está utilizando).

4) Presta atención a lo hilo que se encuentra.

Recuerde, usted necesidad mapas de bits de descarga de un hilo no la interfaz de usuario (usamos una instancia de servicio para actuar como una cola de solicitudes intención), y debe adjuntar mapas de bits para ver la instancia solo en el hilo de la interfaz de usuario.

Tendrá que crear un buen sistema en cola para cargar todo en su caché de mapa de bits fuera del subproceso de interfaz de usuario y luego utilizar un controlador para indicarle a su caché de mapa de bits que rellene ImageViews en el hilo de la interfaz de usuario.

5) Preste atención a sus Colas de descarga.

Si usted es como nosotros y tiene dos pulgares y imágenes a tamaño completo, necesita utilizar ya sea manualmente una cola de prioridad para poner sus peticiones imagen antes de peticiones pulgar, o utilizar dos servicios diferentes (que enqueue sus Intents separados) para descargar pulgares versus imágenes completas.

De lo contrario, puede poner en cola una pantalla llena de descargas pero no responder con una imagen completa hasta que se completen todos los pulgares.

6) Pregunte al sistema cuánta RAM tiene.

Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo(); 
    Debug.getMemoryInfo(memoryInfo); 

7) "onLowMemory()" no hace lo que esperas.

Es para cuando el usuario está ejecutando demasiadas aplicaciones en el teléfono y el sistema operativo necesita recuperar la memoria física de todas las aplicaciones en ejecución.

Esto está totalmente separado de quedarse sin montón de VM de aplicaciones como lo hará fácilmente al cargar demasiados mapas de bits.

A mi leal saber y entender, no recibirá una advertencia, simplemente se bloqueará (aunque puede seguir la información de la memoria con la llamada anterior).

Espero que ayude a tratar de hacer algo inteligente acerca de la descarga y visualización de los pulgares de las redes.

mig

+0

Re utilizando "SoftReference". Ahora, se recomienda un LruCache en su lugar. http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html --- "En el pasado, una implementación popular de la memoria caché era una memoria caché de mapas de bits de referencia suave o WeakReference, sin embargo, esto no es recomendable. Android 2.3 (nivel 9 de la API) el recolector de basura es más agresivo al recopilar referencias débiles/débiles, lo que las hace bastante ineficaces ". – ToolmakerSteve

Cuestiones relacionadas