Domanda

Carico un'immagine dal disco utilizzando Picasso, per esempio., Picasso.with(ctx).load(new File("/path/to/image")).into(imageView), ma ogni volta che salvo una nuova immagine in quel file e aggiorno il mio ImageView, Picasso ha ancora la bitmap memorizzata nella cache.

È possibile invalidare la cache in Picasso?

È stato utile?

Soluzione

Nelle recenti versioni di Picasso, c'è un nuovo metodo per invalidare, senza alcun workaround, quindi penso che la classe personalizzata Picassotools menzionata in precedenza sia ora obsoleta in questo caso

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

Altri suggerimenti

In realtà, in base alla tua risposta, c'è un modo più semplice per farlo senza biblioteca della biblioteca.Aggiungi questa classe al pacchetto Com.SquareUp.Picasso.

package com.squareup.picasso;

public class PicassoTools {

    public static void clearCache (Picasso p) {
        p.cache.clear();
    }
}
.

Poiché la cache ha la visibilità del pacchetto, questa classe Util può cancellare la cache per te.Devi solo chiamarlo:

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

Abort Memory Cache and Disk Cache Controllo indicano il criterio di memoria per flag: emorypolicy.no_cache e networkpolicy.No_cache come sotto snippet di codice:

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

Prova ad usare:

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

Un'altra opzione è quella di eliminare la directory della cache stessa, ad esempio su APP Avvio:

deleteDirectoryTree(context.getCacheDir());
.

Dove:

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

    fileOrDirectory.delete();
}
.

che elimina l'intera directory cache, che va bene se si desidera simulare il primo utilizzo della tua app.Se si desidera eliminare solo la cache Picasso, aggiungere "Picasso-cache" al percorso.

Cosa puoi fare se si desidera eliminare tutte le cache subito, è creare un Picasso.LruCache personalizzato, quindi utilizzare il metodo clear su di esso.

Ecco un campione:

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

Per cancellare la cache:

picassoCache.clear();
.

L'ordine di ricerca delle immagini in Picasso è:Cache di memoria -> Cache del disco -> Rete

Quindi ci sono alcuni scenari di cui abbiamo bisogno per invalidare la cache in Picasso:

1.Invalidare la cache di memoria:

  • Caso utente:Quando l'immagine è già aggiornata nella cache del disco o nell'host remoto
  • Soluzione:Svuota la cache di URL, file, Uri se esistenti

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

.

2.Invalidare la cache di memoria e la cache del disco in linea

※Nota: in linea significa aggiornamento direttamente a ImageView

  • Caso utente:Immagine aggiornata sull'host remoto

  • Soluzione:Interrompe l'immagine sulla cache di memoria e sulla cache del disco, quindi richiede l'immagine sull'host remoto

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

    -> Interrompe la cache di memoria e la cache del disco

.

3.Invalidare la cache di memoria e la cache del disco disconnesso

※ Nota: disconnesso significa aggiornamento, non aggiornamento a ImageView, solo recupero in background per l'utilizzo successivo

  • Caso utente:Conosci l'immagine aggiornata sull'host remoto, ma desideri solo aggiornare la cache solo per utilizzarla in seguito (non aggiornare nella visualizzazione immagine)
  • Soluzione:solo prendere

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

※Nota:Usare fetch() è utile ma consuma anche risorse di rete, quindi considera attentamente, controlla lo scenario 4 di seguito per una soluzione migliore

4.Invalidare la cache di memoria e la cache del disco disconnesso se la cache del disco esiste

  • Caso utente:Invalida la cache solo se già esistente nella cache del disco
  • Soluzione:Dovrebbe controllare il disco utilizzando il parametro:Cache NetworkPolicy.OFFLINE prima del recupero

     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 è una libreria straordinaria, spero che Squareup aggiunga più comodità API per gestire la cache nel prossimo futuro.

Puoi cancellare l'immagine Cache di Picasso impostando la tua cache e cancella che. Questo codice è stato testato su 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();
.

non loop è carina, ma questo approccio ha risolto il mio problema con la cache e Picasso.Usa solo questo quando si desidera invalidare la cache per un URL specifico, questo approccio è lento e probabilmente non è il modo corretto di fare ma funziona per me.

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

Una parte molto importante manca la risposta accettata qui.Ho trovato il trucco da qui: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

Basta chiamare la seguente riga, non cancellerebbe la cache di una foto quando si utilizzano opzioni personalizzate come ridimensionamento, raccolto centrale ecc. Quando si visualizza l'immagine originale.

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

La soluzione:

Durante la visualizzazione dell'immagine, utilizzare il metodo stableKey().

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

Quindi, puoi cancellare la cache di questo file in seguito chiamando questo:

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

Spero che questo ti aiuterà.

You can skip memory cache by skipMemoryCache()

see the following

        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"

Another option is to save the new image into a different file than the original. Since the Picasso bitmap cache is keyed off of the file path, loading the new image from a different file will result in a cache miss. This also has the side benefit of not having to clear the entire cache.

use shutdown() instead As per source code; shutdown will stop accepting further request as well as clear all 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;
  }

Also you can not shutdown singleton instance. So you need to have instance variable for Picasso. Do not forget to reinitialize picasso instance everytime you shutdown() it in order to reuse it

File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top