Almacenamiento en caché de volcado y mapa de bits
Estoy intentando exhibir un listview con muchas imágenes (remotas). Estoy tratando de usar volea para la tarea.
Volley funciona un poco, pero no lo suficientemente bueno. En ImageLoader.get volea tiene el siguiente fragmento de código:
- Transmisión de archivos de audio y almacenamiento en caché
- Error Android Out of Memory con imágenes de Lazy Load
- Enfoque para serializar la clase de modelo de punto final de nube en el sistema de archivos Android
- Caché HTTP con Retrofit 2.0.x
- Almacenamiento en caché de los datos descargados de JSON en la base de datos SQLite - ¿es una buena idea?
final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight); // Try to look up the request in the cache of remote images. Bitmap cachedBitmap = mCache.getBitmap(cacheKey); if (cachedBitmap != null) { // Return the cached bitmap. ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null); imageListener.onResponse(container, true); return container; }
Sin embargo, getCacheKey produce una clave como esta:
/** * Creates a cache key for use with the L1 cache. * @param url The URL of the request. * @param maxWidth The max-width of the output. * @param maxHeight The max-height of the output. */ private static String getCacheKey(String url, int maxWidth, int maxHeight) { return new StringBuilder(url.length() + 12).append("#W").append(maxWidth) .append("#H").append(maxHeight).append(url).toString(); }
Es decir, agrega algunos "metadatos" como el ancho y la altura de la clave.
Esta clave nunca produce un golpe y si la imagen no está en la caché L1 se obtiene en línea. Cuando la imagen se obtiene en línea se guarda en el disco caché, pero Volley lo guarda con la URL (y sólo la URL) como clave.
¿Es este comportamiento esperado? ¿Me estoy perdiendo de algo?
- ¿Cómo integrar Google Drive con Picasso en Android?
- ViewPager + FragmentStatePagerAdapter + cambio de orientación
- Cómo eliminar la caché de aplicaciones para todas las aplicaciones en Android M?
- Android maps v2 se vuelve de baja calidad cuando el área del mapa se mueve automáticamente
- ¿Picasso aplica opciones de redimensionamiento durante fetch ()?
- Dimensionamiento del caché LRU según las capacidades del dispositivo y la memoria libre
- Eliminar archivos almacenados en caché - WebView Android 4.4+
- Android Volley + JSONObjectRequest Almacenamiento en caché
La razón por la que no obtiene ningún resultado es porque el comportamiento predeterminado en Volley para la caché de disco depende de los encabezados HTTP del elemento que está solicitando (en su caso, una imagen).
La forma en que Volley trabaja es:
-
ImageLoader
comprueba la caché L1 de la imagen (caché de memoria proporcionada por usted alImageLoader
en su constructor). Si está disponible devuelva la imagen. - Solicitud procesada por
RequestQueue
. Comprueba la L2 (caché de disco) de la imagen. - Si se encuentra en la caché del disco, compruebe el tiempo de caducidad de la imagen. Si no expiró, regrese.
- Descargar la imagen y devolverla.
- Guardar imagen en cachés.
Si desea que la configuración predeterminada funcione, las imágenes deben tener un encabezado Cache-Control
como max-age=???
Donde los signos de interrogación indican suficientes segundos desde el momento de su descarga.
Si quieres cambiar el comportamiento predeterminado, no estoy seguro, pero creo que tienes que editar el código un poco.
Mire la clase CacheDispatcher
en la fuente Volley.
¿Puede publicar su clase que implemente ImageCache.
Sólo he estado mirando esto y me di cuenta en mi código no estaba agregando el mapa de bits a la caché de memoria cuando se estaba cargando desde el disco, por lo que siempre recargar desde el disco cada vez.
Este es un simple ejemplo de lo que quiero decir y de dónde me iba mal
@Override public Bitmap getBitmap(String cachKey) { Bitmap b = null; //check the memory first b = memoryCache.get(cacheKey); if(b == null){ //memory cache was null, check file cache b = diskLruImageCache.getBitmap(cacheKey); // this is where it needs to be added to your memory cache if(b != null){ memoryCache.put(url, b); } } return b; }
He rastreado este problema en mi propia aplicación hoy. Estaba configurando un tamaño máximo de caché en KB en el constructor, pero informando un tamaño en bytes en sizeOf (), así que nunca se guardó nada en caché.
Esta respuesta me puso en línea recta.
Probablemente está utilizando NetworkImageView para cargar sus imágenes. Puede utilizar ImageView y ImageLoader para hacer lo mismo. Utilizando ImageLoader los metadatos de la clave son como "# W0 # H0" para cualquier tamaño de imagen.
ImageLoader imageLoader = getImageLoader(); imageLoader.get(url, ImageLoader.getImageListener(imageView, defaultDrawable, errorDrawable));
Volley no guardará en caché nada, si el control de caché no está establecido en el encabezado de respuesta.
Compruebe la implementación de la clase HttpHeaderParser en Volley.
El almacenamiento en caché se puede basar en max-age o E-tag. Compruebe su cabecera de respuesta e identifique cualquier cosa que se establezca allí. Se verá algo así.
Cache-Control → public, max-age = 300
Información del encabezado del caché
Esta es la forma exacta en que desea que funcione.
- Pulse la url y obtenga la imagen cuando no esté disponible.
- Cargue la imagen desde la memoria caché si está disponible.
- Comprobación doble si el patrón de soporte de fragmento + vista se implementa correctamente
- Prueba de intentos de Espresso de Android falla al azar con “ init () se debe llamar antes de usar este método “