¿Cómo puedo almacenar en caché las imágenes después de descargarlas de la web?
141
Y ahora la frase clave: usa el caché del sistema.
URL url = new URL(strUrl);
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
}
Proporciona memoria y caché flash-rom, compartido con el navegador.
grr. Ojalá alguien me hubiera dicho eso antes de escribir mi propio administrador de caché.
connection.getContent()
siempre me devuelve un InputStream, ¿qué estoy haciendo mal?Bitmap response = BitmapFactory.decodeStream((InputStream)connection.getContent());
En cuanto a la elegante
connection.setUseCaches
solución anterior: lamentablemente, no funcionará sin un esfuerzo adicional. Deberá instalar unResponseCache
usoResponseCache.setDefault
. De lo contrario,HttpURLConnection
ignorará silenciosamente elsetUseCaches(true)
bit.Vea los comentarios en la parte superior de
FileResponseCache.java
para más detalles:http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(Publicaría esto en un comentario, pero aparentemente no tengo suficiente SO karma).
fuente
HttpResponseCache
, es posible que encuentre elHttpResponseCache.getHitCount()
0. devuelto No estoy seguro, pero creo que es porque el servidor web que solicita no usa encabezados de almacenamiento en caché en ese caso. Para que el almacenamiento en caché funcione de todos modos, useconnection.addRequestProperty("Cache-Control", "max-stale=" + MAX_STALE_CACHE);
..getContent()
método porque las respuestas 304 no tienen un cuerpo de respuesta asociado según el estándar RFC.Conviértalos en mapas de bits y luego guárdelos en una colección (HashMap, List, etc.) o puede escribirlos en la tarjeta SD.
Al almacenarlos en el espacio de la aplicación utilizando el primer enfoque, es posible que desee envolverlos alrededor de una java.lang.ref.SoftReference específicamente si sus números son grandes (de modo que se recolectan basura durante la crisis). Sin embargo, esto podría provocar una recarga.
escribirlos en la tarjeta SD no requerirá una recarga; solo un permiso de usuario.
fuente
Uri
referencia de ruta que pueda pasarImageView
y otras vistas personalizadas. Porque cada vez que estéscompress
, estarás perdiendo calidad. Por supuesto, esto es cierto solo para algoritmos con pérdida. Este método también le permitiría incluso almacenar un hash del archivo y usarlo la próxima vez que solicite el archivo desde el servidorIf-None-Match
y losETag
encabezados.Úselo
LruCache
para almacenar en caché las imágenes de manera eficiente. Usted puede leer acercaLruCache
de Android sitio para desarrolladoresHe utilizado la siguiente solución para la descarga de imágenes y el almacenamiento en caché en Android. Puedes seguir los pasos a continuación:
PASO 1: crea la clase con nombre
ImagesCache
. he usadoSingleton object for this class
PASO 2:
cree otra clase llamada DownloadImageTask que se usa si el mapa de bits no está disponible en caché, lo descargará desde aquí:
PASO 3: Uso de su
Activity
oAdapter
Nota: si desea cargar la imagen desde la URL desde la
Activity
clase. Use el segundo Constructor deDownloadImageTask
, pero si desea mostrar la imagen desde elAdapter
primer Constructor deDownloadImageTask
(por ejemplo, tiene una imagenListView
y está configurando la imagen desde 'Adaptador')USO DE LA ACTIVIDAD:
USO DEL ADAPTADOR:
Nota:
cache.initializeCache()
puede usar esta declaración en la primera Actividad de su aplicación. Una vez que haya inicializado el caché, nunca necesitará inicializarlo cada vez que use laImagesCache
instancia.Nunca soy bueno para explicar las cosas, pero espero que esto ayude a los principiantes a saber cómo usar el caché
LruCache
y su uso :)EDITAR:
Hoy en día hay bibliotecas muy famosas conocidas como
Picasso
yGlide
que se pueden usar para cargar imágenes de manera muy eficiente en la aplicación de Android. Pruebe esta biblioteca muy simple y útil Picasso para Android y Glide para Android . No necesita preocuparse por las imágenes de caché.También puedes visitar el blog para ver la diferencia entre Glide y Picasso
fuente
if(cache == null)
resolvió mi problema! :)Para descargar una imagen y guardarla en la tarjeta de memoria, puede hacerlo así.
No olvide agregar el permiso de Internet a su manifiesto:
fuente
Consideraría usar el caché de imágenes de droidfu. Implementa un caché de imágenes en memoria y en disco. También obtiene un WebImageView que aprovecha la biblioteca ImageCache.
Aquí está la descripción completa de droidfu y WebImageView: http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
fuente
Probé SoftReferences, se recuperan de manera demasiado agresiva en Android que sentí que no tenía sentido usarlos.
fuente
SoftReference
s. Recomiendan usar suLruCache
en su lugar.Como sugirió Thunder Rabbit, ImageDownloader es el mejor para el trabajo. También encontré una ligera variación de la clase en:
http://theandroidcoder.com/utilities/android-image-download-and-caching/
La principal diferencia entre los dos es que ImageDownloader utiliza el sistema de almacenamiento en caché de Android, y el modificado utiliza el almacenamiento interno y externo como almacenamiento en caché, manteniendo las imágenes en caché de forma indefinida o hasta que el usuario lo elimine manualmente. El autor también menciona la compatibilidad con Android 2.1.
fuente
Esta es una buena captura de Joe. El ejemplo de código anterior tiene dos problemas: uno: el objeto de respuesta no es una instancia de Bitmap (cuando mi URL hace referencia a un jpg, como http: \ website.com \ image.jpg, es un
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl $ LimitedInputStream).
En segundo lugar, como señala Joe, no se produce el almacenamiento en caché sin configurar una memoria caché de respuesta. Los desarrolladores de Android deben rodar su propio caché. Aquí hay un ejemplo para hacerlo, pero solo se almacena en memoria caché, lo que realmente no es la solución completa.
http://codebycoffee.com/2010/06/29/using-responsecache-in-an-android-app/
La API de almacenamiento en caché de URLConnection se describe aquí:
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-cache.html
Sigo pensando que esta es una buena solución para seguir esta ruta, pero todavía tienes que escribir un caché. Suena divertido, pero prefiero escribir características.
fuente
Hay una entrada especial en la sección de entrenamiento oficial de Android sobre esto: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
La sección es bastante nueva, no estaba allí cuando se hizo la pregunta.
La solución sugerida es usar un LruCache. Esa clase se introdujo en Honeycomb, pero también se incluye en la biblioteca de compatibilidad.
Puede inicializar un LruCache configurando el número máximo de entradas y las clasificará automáticamente y las limpiará menos cuando supere el límite. Aparte de eso, se utiliza como un mapa normal.
El código de muestra de la página oficial:
Anteriormente, SoftReferences era una buena alternativa, pero ya no, citando desde la página oficial:
fuente
Considere usar la biblioteca Universal Image Loader de Sergey Tarasevich . Viene con:
Universal Image Loader permite una gestión de caché detallada para las imágenes descargadas, con las siguientes configuraciones de caché:
UsingFreqLimitedMemoryCache
: El mapa de bits utilizado con menos frecuencia se elimina cuando se excede el límite de tamaño de caché.LRULimitedMemoryCache
: El mapa de bits utilizado menos recientemente se elimina cuando se supera el límite de tamaño de caché.FIFOLimitedMemoryCache
: La regla FIFO se usa para eliminación cuando se excede el límite de tamaño de caché.LargestLimitedMemoryCache
: El mapa de bits más grande se elimina cuando se excede el límite de tamaño de caché.LimitedAgeMemoryCache
: El objeto en caché se elimina cuando su antigüedad excede el valor definido .WeakMemoryCache
: Una memoria caché con solo referencias débiles a mapas de bits.Un ejemplo de uso simple:
Este ejemplo usa el valor predeterminado
UsingFreqLimitedMemoryCache
.fuente
Lo que realmente funcionó para mí fue configurar ResponseCache en mi clase Main:
y
al descargar bitmap.
http://practicaldroid.blogspot.com/2013/01/utilizing-http-response-cache.html
fuente
Google libs-for-android tiene buenas bibliotecas para administrar imágenes y caché de archivos.
http://code.google.com/p/libs-for-android/
fuente
Había estado luchando con esto por algún tiempo; las respuestas que usan SoftReferences perderían sus datos demasiado rápido. Las respuestas que sugieren crear una instancia de RequestCache eran demasiado desordenadas, además, nunca pude encontrar un ejemplo completo.
Pero ImageDownloader.java funciona maravillosamente para mí. Utiliza un HashMap hasta que se alcanza la capacidad o hasta que se produce el tiempo de espera de purga, luego las cosas se mueven a una SoftReference, utilizando así lo mejor de ambos mundos.
fuente
Sugiero IGNICIÓN esto es incluso mejor que Droid fu
https://github.com/kaeppler/ignition
https://github.com/kaeppler/ignition/wiki/Sample-applications
fuente
Incluso la respuesta posterior, pero escribí un Administrador de imágenes de Android que maneja el almacenamiento en caché de forma transparente (memoria y disco). El código está en Github https://github.com/felipecsl/Android-ImageManager
fuente
Respuesta tardía, pero pensé que debería agregar un enlace a mi sitio porque he escrito un tutorial sobre cómo hacer un caché de imágenes para Android:
http://squarewolf.nl/2010/11/android-image-cache/Actualización: el la página se ha desconectado porque la fuente estaba desactualizada. Me uno a @elenasys en su consejo de usar Ignition .Entonces, a todas las personas que se topan con esta pregunta y no han encontrado una solución: ¡espero que disfruten! = D
fuente
Respuesta tardía, pero creo que esta biblioteca ayudará mucho con el almacenamiento en caché de imágenes: https://github.com/crypticminds/ColdStorage .
Simplemente anote ImageView con @LoadCache (R.id.id_of_my_image_view, "URL_to_downlaod_image_from) y se encargará de descargar la imagen y cargarla en la vista de imagen. También puede especificar una imagen de marcador de posición y cargar la animación.
La documentación detallada de la anotación está presente aquí: - https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation
fuente