Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Android: Estrategia de caché de imágenes y tamaño de caché de memoria

Estoy implementando un sistema de caché de imágenes para almacenar en caché la imagen descargada.

Mi estrategia se basa en caché de dos niveles: Nivel de memoria y nivel de disco.

  • CookieSyncManager está ahora obsoleto, ¿qué puedo usar en su lugar?
  • Ocultar barra del sistema de la tableta
  • Android Studio no muestra módulos en la estructura del proyecto
  • La llamada startActivityForResult de Fragment no invoca onActivityResult
  • Cómo mover la disposición para arriba cuando el teclado suave se muestra android
  • ¿Las mejores prácticas para usar el reino con una vista de reciclador?
  • Mi clase es muy similar a la clase utilizada en el proyecto droidfu

    Mis imágenes descargadas se ponen en un hashmap y el objeto Bitmap se envuelve dentro de un objeto SoftRererence. También cada imagen se guarda permanentemente en el disco. Si no se encuentra una imagen solicitada en Hashmap<String,SoftReference<Bitmap>> , se buscará en el disco, se leerá y volverá a insertarse en el hashmap. De lo contrario, la imagen se descargará de la red. Desde que almacenar las imágenes en el dispositivo phisical momery, he añadido un cheque para preservar el espacio del dispositivo y permanecer bajo un 1M de espacio ocupado:

     private void checkCacheUsage() { long size = 0; final File[] fileList = new File(mCacheDirPath).listFiles(); Arrays.sort(fileList, new Comparator<File>() { public int compare(File f1, File f2) { return Long.valueOf(f2.lastModified()).compareTo( f1.lastModified()); } }); for (File file : fileList) { size += file.length(); if (size > MAX_DISK_CACHE_SIZE) { file.delete(); Log.d(ImageCache.class.getSimpleName(), "checkCacheUsage: Size exceeded " + size + "(" + MAX_DISK_CACHE_SIZE + ") wiping older file {"+file.toString()+"}"); } } } 

    Este método se llama en algún momento después de una escritura de disco:

     Random r = new Random(); int ra = r.nextInt(10); if (ra % 2 == 0){ checkCacheUsage(); } 

    Lo que me gustaría añadir es la misma verificación en el tamaño HashMap para evitar que crezca demasiado. Algo como esto:

     private synchronized void checkMemoryCacheUsage(){ long size = 0; for (SoftReference<Bitmap> a : cache.values()) { final Bitmap b = a.get(); if (b != null && ! b.isRecycled()){ size += b.getRowBytes() * b.getHeight(); } if (size > MAX_MEMORY_SIZE){ //Remove some elements from the cache } } Log.d(ImageCache.class.getSimpleName(), "checkMemoryCacheUsage: " + size + " in memory"); } 

    Mi pregunta es: ¿Qué podría ser un valor MAX_MEMORY_SIZE correcto? Además, ¿Es un buen enfoque? Una buena respuesta también podría ser: "¡No lo hagas! SoftReference ya es suficiente"

  • Emulador de Android "emulador: ERROR: la imagen de datos de usuario es utilizada por otro emulador. Abortar "
  • Android: <include> con RippleEffect & StateListAnimator
  • ¿Cómo se centra un texto en el diseño?
  • Android: Clonación de un drawable para hacer un StateListDrawable con filtros
  • Botones flotantes de Android sobre una vista
  • Cómo deshabilitar edittext en android
  • 3 Solutions collect form web for “Android: Estrategia de caché de imágenes y tamaño de caché de memoria”

    ¡No lo hagas! SoftReference ya es suficiente! En realidad SoftReference está diseñado para hacer exactamente lo que necesita. A veces, SoftReference no hace lo que necesita. A continuación, acaba de deshacerse de SoftReference y escribir su propia lógica de gestión de memoria. Pero en la medida en que utilice SoftReference no debería preocuparse por el consumo de memoria, SoftReference lo hace por usted.

    Estoy utilizando un tercio de la pila para el caché de la imagen.

     int memoryInMB = activityManager.getMemoryClass(); long totalAppHeap = memoryInMB * 1024 * 1024; int runtimeCacheLimit = (int)totalAppHeap/3; 

    Por cierto, sobre la referencia suave, en Android Soft referencias no funcionan como esperas. Hay una cuestión de plataforma que las referencias suaves se recogen demasiado pronto, incluso cuando hay un montón de memoria libre.

    Compruebe http://code-gotcha.blogspot.com/2011/09/softreference.html

    He estado buscando en diferentes mecanismos de almacenamiento en caché para mi bitmaps a escala, memoria y ejemplos de caché de disco. Los ejemplos donde a complejo para mis necesidades, por lo que terminé haciendo mi propio caché de memoria de mapa de bits con LruCache. Puede ver un ejemplo de código de trabajo aquí o usar este código:

    Memoria caché:

     public class Cache { private static LruCache<Integer, Bitmap> bitmaps = new BitmapLruCache(); public static Bitmap get(int drawableId){ Bitmap bitmap = bitmaps.get(drawableId); if(bitmap != null){ return bitmap; } else { bitmap = SpriteUtil.createScaledBitmap(drawableId); bitmaps.put(drawableId, bitmap); return bitmap; } } } 

    BitmapLruCache:

     public class BitmapLruCache extends LruCache<Integer, Bitmap> { private final static int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); private final static int cacheSize = maxMemory / 2; public BitmapLruCache() { super(cacheSize); } @Override protected int sizeOf(Integer key, Bitmap bitmap) { // The cache size will be measured in kilobytes rather than number of items. return bitmap.getRowBytes() * bitmap.getHeight() / 1024; } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.