Invalider le cache dans Picasso

Je charge une image à partir du disque en utilisant Picasso , par exemple, Picasso.with(ctx).load(new File("/path/to/image")).into(imageView) , mais chaque fois que je sauvegarde une nouvelle image dans ce fichier, et rafraîchir mon ImageView , Picasso a toujours le bitmap mis en cache.

Est-il possible d’invalider le cache dans Picasso?

Dans les versions récentes de Picasso, il existe une nouvelle méthode pour invalider, sans solutions de contournement, alors je pense que la classe personnalisée de PicassoTools mentionnée précédemment est désormais obsolète.

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

En fait, sur la base de votre propre réponse, il existe un moyen plus simple de le faire sans forcer la bibliothèque. Ajoutez cette classe au package com.squareup.picasso.

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

Comme le cache a une visibilité sur les paquets, cette classe util peut effacer le cache pour vous. Vous devez juste l’appeler:

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

Interrompre le contrôle de la mémoire cache et du cache disque en indiquant la stratégie de mémoire par indicateur: emoryPolicy.NO_CACHE et NetworkPolicy.NO_CACHE comme ci-dessous:

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

Essayez d’utiliser:

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

Une autre option consiste à supprimer le répertoire cache lui-même, par exemple au démarrage de l’application:

 deleteDirectoryTree(context.getCacheDir()); 

où:

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

Cela supprime tout le répertoire de cache, ce qui est bien si vous voulez simuler la première utilisation de votre application. Si vous souhaitez uniquement supprimer le cache Picasso, ajoutez “picasso-cache” au chemin.

Ce que vous pouvez faire si vous souhaitez supprimer tout le cache en même temps, consiste à créer un Picasso.LruCache personnalisé, puis à utiliser la méthode clear .

Voici un exemple:

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

Pour effacer le cache:

 picassoCache.clear(); 

L’ordre de recherche de l’image dans Picasso est le suivant: Cache mémoire -> Cache disque -> Réseau

Donc, il y a peu de scénarios dont nous avons besoin d’invalider le cache dans Picasso:

1.Invalider le cache mémoire:

  • Usercase: lorsque l’image est déjà mise à jour dans le cache disque ou l’hôte distant
  • Solution: effacez le cache de l’URL, du fichier, de l’Uri s’il existe

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

.

2. Invalider le cache mémoire et le cache disque en ligne

: Note: mise à jour en ligne directement à ImageView

  • Cas utilisateur: Image mise à jour sur l’hôte distant

  • Solution: abandonner l’image sur le cache mémoire et le cache disque, puis demander une image sur l’hôte distant

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

    -> Abandonner le cache mémoire et le cache disque

.

3.Invalider le cache mémoire et le cache disque hors ligne

: Note: mise à jour moyenne hors ligne ne pas mettre à jour à ImageView, juste extraire en arrière-plan à utiliser plus tard

  • Cas utilisateur: vous savez que l’image de l’hôte distant a été mise à jour, mais que vous souhaitez uniquement mettre à jour le cache et l’utiliser par la suite (ne pas mettre à jour en vue image)
  • Solution: chercher uniquement

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

: Remarque: Utiliser fetch () est une bonne chose, mais consum également des ressources réseau. Veuillez donc examiner attentivement le scénario 4 ci-dessous pour une meilleure solution.

4.Invalider le cache mémoire et le cache disque hors ligne si le cache disque existe

  • Cas utilisateur: invalider uniquement le cache s’il existe déjà dans le cache disque
  • Solution: Vérifiez le disque en utilisant le paramètre: cache NetworkPolicy.OFFLINE avant la récupération

      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 est une incroyable libs, j’espère que squareup appenda plus de commodité pour gérer le cache dans un futur proche.

Vous pouvez effacer le cache image de picasso en définissant votre propre cache et effacer cela. Ce code a été testé sur 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(); 

Ne boucle pas, mais cette approche a corrigé mon problème avec le cache et Picasso. Utilisez-le uniquement lorsque vous souhaitez invalider le cache pour une URL spécifique, cette approche est lente et n’est probablement pas la bonne façon de procéder mais fonctionne pour moi.

  Ssortingng url = "http://soffr.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); 

Une partie très importante manque dans la réponse acceptée ici. J’ai trouvé le truc ici: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

Il suffit d’appeler la ligne suivante pour ne pas effacer le cache d’une photo lorsque vous utilisez des options personnalisées telles que le redimensionnement, le recadrage, etc. lors de l’affichage de l’image d’origine.

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

La solution:

Lors de l’affichage de l’image, utilisez la méthode stableKey() .

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

Ensuite, vous pouvez effacer le cache de ce fichier ultérieurement en appelant ceci:

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

J’espère que cela aidera.

Vous pouvez ignorer le cache mémoire par skipMemoryCache()

voir ce qui suit

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

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

Une autre option consiste à enregistrer la nouvelle image dans un fichier différent de celui d’origine. Étant donné que le cache bitmap Picasso est extrait du chemin du fichier, le chargement de la nouvelle image à partir d’un fichier différent entraînera un échec du cache. Cela a également l’avantage de ne pas avoir à effacer la totalité du cache.

utilisez plutôt shutdown() selon le code source; L’arrêt arrêtera d’accepter une demande supplémentaire ainsi que d’effacer tout le cache

  /** 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; } 

Aussi, vous ne pouvez pas arrêter l’instance singleton. Vous devez donc avoir une variable d’instance pour Picasso . N’oubliez pas de réinitialiser l’instance de picasso à chaque fois que vous l’arrêtez pour le réutiliser

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