Invalidar el caché en Picasso

Picasso.with(ctx).load(new File("/path/to/image")).into(imageView) una imagen del disco usando Picasso , por ejemplo, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView) , pero cada vez que Picasso.with(ctx).load(new File("/path/to/image")).into(imageView) una nueva imagen en ese archivo, y actualice mi ImageView , Picasso aún tiene el bitmap en caché.

¿Es posible invalidar el caché en Picasso?

En las versiones recientes de Picasso, hay un nuevo método para invalidar, sin ningún tipo de soluciones, así que creo que la clase PicassoTools personalizada mencionada anteriormente, ahora está obsoleta en este caso

 Picasso.with(getActivity()).invalidate(file); 

En realidad, según su propia respuesta, hay una manera más fácil de hacerlo sin bifurcar la biblioteca. Agregue esta clase al paquete com.squareup.picasso.

 package com.squareup.picasso; public class PicassoTools { public static void clearCache (Picasso p) { p.cache.clear(); } } 

Debido a que la memoria caché tiene visibilidad del paquete, esta clase de utilidad puede borrar la memoria caché por usted. Solo tienes que llamarlo:

 PicassoTools.clearCache(Picasso.with(context)); 

Anule la memoria caché y la comprobación de la memoria caché de disco indicando la política de memoria por indicador: emoryPolicy.NO_CACHE y NetworkPolicy.NO_CACHE como el siguiente fragmento de código:

  mPicasso.with(mContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .resize(512, 512) .error(R.drawable.login) .noFade() .into(imageView); 

Tratar de usar:

 Picasso.with(ctx).load(new File("/path/to/image")).skipMemoryCache().into(imageView) 

Otra opción es eliminar el directorio de caché, por ejemplo, en el inicio de la aplicación:

 deleteDirectoryTree(context.getCacheDir()); 

dónde:

 /** * Deletes a directory tree recursively. */ public static void deleteDirectoryTree(File fileOrDirectory) { if (fileOrDirectory.isDirectory()) { for (File child : fileOrDirectory.listFiles()) { deleteDirectoryTree(child); } } fileOrDirectory.delete(); } 

Eso borra todo el directorio de caché, lo cual está bien si quieres simular el primer uso de tu aplicación. Si solo desea eliminar la memoria caché Picasso, agregue “picasso-cache” a la ruta.

Lo que puede hacer si desea eliminar todo el caché a la vez, es crear un Picasso.LruCache personalizado, y luego usar el método clear en él.

Aquí hay una muestra:

 Picasso.Builder builder = new Picasso.Builder(this); LruCache picassoCache = new LruCache(this); builder.memoryCache(picassoCache); Picasso.setSingletonInstance(builder.build()); 

Para borrar el caché:

 picassoCache.clear(); 

El orden de la imagen de búsqueda en Picasso es: memoria caché -> memoria caché de disco -> red

Así que hay algunos escenarios que necesitamos para invalidar el caché en Picasso:

1. Invalidar memoria caché:

  • Usercase: cuando la imagen ya se actualiza en el caché de disco o en el host remoto
  • Solución: borrar caché de Url, Archivo, Uri si existe

     mPicasso.with(appContext).invalidate(File); mPicasso.with(appContext).invalidate(Url); mPicasso.with(appContext).invalidate(Uri); 

.

2. Invalidar memoria caché y caché de disco en línea

※ nota: actualización media en línea directamente a ImageView

  • Caso del usuario: Imagen actualizada en el host remoto

  • Solución: Anule la imagen en la memoria caché y la memoria caché de disco, luego solicite una imagen en el host remoto.

     mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageView); 

    -> Abortar memoria caché y caché de disco

.

3. Invalidar memoria caché y caché de disco fuera de línea

※ nota: la actualización sin conexión significa que no se actualizó a ImageView, solo aparece el fondo para usar más tarde

  • Caso del usuario: Usted sabe que la imagen en el host remoto está actualizada, pero solo desea actualizar el caché solo para usar después (no actualizar a la vista de imagen)
  • Solución: buscar solo

      mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .networkPolicy(NetworkPolicy.NO_CACHE) .fetch(); 

※ Nota: El uso de fetch () es bueno pero también consume recursos de red, así que por favor considere cuidadosamente, verifique el escenario 4 a continuación para una mejor solución

4. Invalidar caché de memoria y caché de disco Sin conexión si existe memoria caché de disco

  • Caso del usuario: solo invalida la caché si ya existe en la memoria caché de disco
  • Solución: debe verificar el disco utilizando el parámetro: caché NetworkPolicy.OFFLINE antes de buscar

      mPicasso.with(appContext) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .networkPolicy(NetworkPolicy.OFFLINE) .fetch(new Callback() { @Override public void onSuccess() { //Success: mean disk cache exist -> should do actual fetch picasso.load(url).fetch(); } @Override public void onError() { //Failed: mean disk cache not exist } }); 

Picasso es una libs increíble, espero que Squareup agregue más conveniencia API para administrar el caché en el futuro próximo.

Puede borrar el caché de imágenes de picasso configurando su propio caché y borrando eso. Este código fue probado en Picasso 2.5.0

 private Picasso picasso; private LruCache picassoLruCache; picassoLruCache = new LruCache(context); // Set cache picasso = new Picasso.Builder(context) // .memoryCache(picassoLruCache) // .build(); // Clear cache picassoLruCache.clear(); 

No funciona bien, pero este enfoque solucionó mi problema con el caché y Picasso. Solo use esto cuando quiera invalidar la caché para una URL específica, este enfoque es lento y probablemente no sea la forma correcta de hacerlo, pero funciona para mí.

  String url = "http://sofes.miximages.com/android/f"; Picasso.with(this).invalidate(url); Picasso.with(this) .load(url) .networkPolicy( NetworkUtils.isConnected(this) ? NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE) .resize(200, 200) .centerCrop() .placeholder(R.mipmap.ic_avatar) .error(R.mipmap.ic_avatar) .into(imageView); 

Una parte muy importante falta en la respuesta aceptada aquí. Encontré el truco aquí: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

Simplemente llamando a la siguiente línea, no borrará la memoria caché de una foto cuando use opciones personalizadas como cambiar el tamaño, centrar el cultivo, etc., cuando muestre la imagen original.

 Picasso.with(getContext()).invalidate(file); 

La solución:

Al mostrar la imagen, use el método stableKey() .

 Picasso.with(getContext()).load(new File(fileUri)) .skipMemoryCache() .placeholder(R.drawable.placeholder) .stableKey(fileUri) .into(imageview); 

Luego, puede borrar el caché de este archivo más tarde llamando a esto:

 Picasso.with(getContext()).invalidate(fileUri); 

Espero que esto ayude

Puede omitir la memoria caché mediante skipMemoryCache()

mira lo siguiente

  Picasso.with(this) .load(IMAGE_URL) .skipMemoryCache() .placeholder(R.drawable.placeholder) .error(R.drawable.no_image) .into(mImageViewPicasso); 

gradle compile "com.squareup.picasso:picasso:2.4.0"

Otra opción es guardar la nueva imagen en un archivo diferente al original. Como la memoria caché de bitmap de Picasso está desactivada en la ruta del archivo, la carga de la nueva imagen desde un archivo diferente dará como resultado una falta de memoria caché. Esto también tiene el beneficio adicional de no tener que borrar todo el caché.

use shutdown() lugar Según el código fuente; shutdown dejará de aceptar solicitudes adicionales y borrará todo el caché

  /** Stops this instance from accepting further requests. */ public void shutdown() { if (this == singleton) { throw new UnsupportedOperationException("Default singleton instance cannot be shutdown."); } if (shutdown) { return; } cache.clear(); cleanupThread.shutdown(); stats.shutdown(); dispatcher.shutdown(); for (DeferredRequestCreator deferredRequestCreator : targetToDeferredRequestCreator.values()) { deferredRequestCreator.cancel(); } targetToDeferredRequestCreator.clear(); shutdown = true; } 

Además, no puede cerrar la instancia de singleton. Entonces necesitas tener una variable de instancia para Picasso . No olvide reiniciar la instancia de picasso cada vez que la shutdown() para volver a utilizarla

 File f = new File(path, name); Picasso.with(this).invalidate(Uri.fromFile(f));