web-dev-qa-db-fra.com

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 j'enregistre une nouvelle image dans ce fichier et que j'actualise mon ImageView, Picasso a toujours le bitmap mis en cache.

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

72
Maarten

Dans les versions récentes de Picasso, il existe une nouvelle méthode d'invalidation, sans solution de contournement. Je pense donc que la classe PicassoTools personnalisée mentionnée précédemment est maintenant obsolète.

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

En fait, sur la base de votre propre réponse, il existe un moyen plus simple de le faire sans manipuler 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();
    }
}

Étant donné que le cache a la visibilité du package, cette classe utilitaire peut vider le cache à votre place. Vous devez juste l'appeler:

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

Abandonnez les caches de mémoire et les caches de disque en indiquant la stratégie de mémoire par indicateur: emoryPolicy.NO_CACHE et NetworkPolicy.NO_CACHE comme le code 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)
14
user3361741

Si vous souhaitez supprimer tout le cache en même temps, vous pouvez créer un fichier personnalisé Picasso.LruCache, puis utilisez la méthode clear.

Voici un échantillon:

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

Pour vider le cache:

picassoCache.clear();
11
Aerilys

Une autre option consiste à supprimer le répertoire de 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 très bien si vous souhaitez simuler la première utilisation de votre application. Si vous souhaitez uniquement supprimer le cache Picasso, ajoutez "picasso-cache" au chemin.

11
Lawrence Kesteloot

L'ordre de recherche des images dans Picasso est le suivant: Cache mémoire -> Cache disque -> Réseau

Il y a donc peu de scénarios pour 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: Effacer le cache de l'URL, du fichier et de l'URI, le cas échéant

    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

Remarque: en ligne signifie une mise à jour directe vers ImageView

  • Cas utilisateur: image mise à jour sur l'hôte distant

  • Solution: Abandonnez l'image sur la mémoire cache et la mémoire cache du disque, puis demandez 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

.

.Invalider le cache mémoire et le cache disque Hors ligne

Remarque: Hors ligne la mise à jour moyenne n'est pas mise à jour vers ImageView;

  • Cas utilisateur: vous savez que l'image sur l'hôte distant a été mise à jour, mais vous souhaitez uniquement mettre à jour le cache pour l'utiliser ultérieurement (ne pas mettre à jour dans la vue d'image)
  • Solution: chercher seulement

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

Remarque: utiliser fetch () est une bonne chose, mais elle consomme é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 le cache uniquement s'il existe déjà dans le cache de disque
  • Solution: Le disque doit-il être vérifié à l'aide du 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 bibliothèque incroyable, j'espère que squareup va ajouter une API plus pratique pour gérer le cache dans les années à venir.

9
NguyenDat

Vous pouvez vider le cache d’images de picasso en définissant votre propre cache et l’effacer. 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();
8
Stanley Kou

La boucle n'est pas belle, mais cette approche a résolu mon problème de cache et de Picasso. Utilisez-le uniquement lorsque vous souhaitez invalider le cache pour une URL spécifique. Cette approche est lente et ne constitue probablement pas la bonne façon de procéder, mais fonctionne pour moi.

    String url = "http://www.blablabla.com/Raiders.jpg";
    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);
6
João Machete

Une partie très importante manque à la réponse acceptée ici. J'ai trouvé l'astuce à partir d'ici: http://blogs.candoerz.com/question/124660/Android-image-cache-is-not-clearing-in-picasso.aspx

Le simple fait d'appeler la ligne suivante n'a pas pour effet d'effacer le cache d'une photo lorsque vous utilisez des options personnalisées telles que redimensionner, rogner au centre, 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 pourrez effacer le cache de ce fichier ultérieurement en appelant ceci:

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

J'espère que cela aidera.

2
OrangeTree

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);

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

1
Android Dev

Une autre option consiste à enregistrer la nouvelle image dans un fichier différent de celui de l'original. Étant donné que le cache bitmap Picasso est supprimé du chemin d'accès au fichier, le chargement de la nouvelle image à partir d'un fichier différent entraînera une erreur de cache. Cela présente également l’avantage supplémentaire de ne pas avoir à effacer tout le cache.

0
Ilan Klinghofer

utilisez shutdown() à la place Comme pour le code source; l’arrêt cessera d’accepter toute autre requête et 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 shutdown() afin de pouvoir le réutiliser

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