Frage

Ich lade ein Bild von der Festplatte mit Picasso, z.B., Picasso.with(ctx).load(new File("/path/to/image")).into(imageView), aber immer wenn ich ein neues Bild in dieser Datei speichere und meine aktualisiere ImageView, Picasso hat die Bitmap immer noch zwischengespeichert.

Ist es möglich, den Cache in Picasso ungültig zu machen?

War es hilfreich?

Lösung

In den neueren Versionen von Picasso gibt es eine neue Methode zum Ungültigmachen ohne Problemumgehungen, daher denke ich, dass die zuvor erwähnte benutzerdefinierte PicassoTools-Klasse in diesem Fall jetzt veraltet ist

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

Andere Tipps

Basierend auf Ihrer eigenen Antwort gibt es tatsächlich einen einfacheren Weg, dies zu tun, ohne die Bibliothek zu teilen.Fügen Sie diese Klasse zum Paket com.squareup.picasso hinzu.

package com.squareup.picasso;

public class PicassoTools {

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

Da der Cache über Paketsichtbarkeit verfügt, kann diese Util-Klasse den Cache für Sie leeren.Man muss es nur nennen:

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

Abbrechen der Speicher-Cache- und Festplatten-Cache-Prüfung durch Angabe der Speicherrichtlinie durch Flag:emoryPolicy.NO_CACHE und NetworkPolicy.NO_CACHE wie untenstehendes Code-Snippet:

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

Versuchen zu benutzen:

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

Eine andere Möglichkeit besteht darin, das Cache-Verzeichnis selbst zu löschen, beispielsweise beim Start der App:

deleteDirectoryTree(context.getCacheDir());

Wo:

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

    fileOrDirectory.delete();
}

Dadurch wird das gesamte Cache-Verzeichnis gelöscht. Dies ist in Ordnung, wenn Sie die erstmalige Verwendung Ihrer App simulieren möchten.Wenn Sie nur den Picasso-Cache löschen möchten, fügen Sie „picasso-cache“ zum Pfad hinzu.

Wenn Sie den gesamten Cache auf einmal löschen möchten, können Sie einen benutzerdefinierten Cache erstellen Picasso.LruCache, und verwenden Sie dann die clear Methode darauf.

Hier ist ein Beispiel:

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

So leeren Sie den Cache:

picassoCache.clear();

Die Reihenfolge der Suchbilder in Picasso ist:Speichercache -> Festplattencache -> Netzwerk

Daher gibt es einige Szenarien, in denen wir den Cache in Picasso ungültig machen müssen:

1. Speichercache ungültig machen:

  • Benutzerfall:Wenn das Image bereits im Festplatten-Cache oder auf dem Remote-Host aktualisiert wird
  • Lösung:Cache von URL, Datei und Uri löschen, falls vorhanden

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

.

2. Speicher-Cache und Festplatten-Cache ungültig machen Online

※Notiz: Online bedeuten, direkt auf ImageView zu aktualisieren

  • Anwendungsfall:Bild auf Remote-Host aktualisiert

  • Lösung:Bild im Speichercache und Festplattencache abbrechen und dann Bild auf dem Remote-Host anfordern

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

    -> Speichercache und Festplattencache abbrechen

.

3. Speicher-Cache und Festplatten-Cache ungültig machen Offline

※ Notiz: Offline Ich meine, dass es sich um ein Update handelt, nicht um ein Update auf ImageView, sondern nur um einen Hintergrundabruf zur späteren Verwendung

  • Anwendungsfall:Sie wissen, dass das Bild auf dem Remote-Host aktualisiert wurde, möchten aber nur den Cache aktualisieren, um ihn später zu verwenden (nicht in die Bildansicht aktualisieren).
  • Lösung:Nur abrufen

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

※Notiz:Die Verwendung von fetch() ist gut, verbraucht aber auch Netzwerkressourcen. Überlegen Sie sich das bitte sorgfältig und sehen Sie sich Szenario 4 unten an, um eine bessere Lösung zu finden

4. Speicher-Cache und Festplatten-Cache ungültig machen Offline ob Festplatten-Cache vorhanden ist

  • Anwendungsfall:Cache nur ungültig machen, wenn er bereits im Festplatten-Cache vorhanden ist
  • Lösung:Sollte die Festplatte mithilfe des folgenden Parameters überprüfen:NetworkPolicy.OFFLINE-Cache vor dem Abruf

     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 ist eine erstaunliche Bibliothek. Ich hoffe, dass Squareup in der kommenden Zukunft eine komfortablere API für die Verwaltung des Caches hinzufügen wird.

Sie können den Bildcache von Picasso löschen, indem Sie Ihren eigenen Cache einrichten und diesen löschen.Dieser Code wurde auf Picasso 2.5.0 getestet

private Picasso picasso;
private LruCache picassoLruCache;

picassoLruCache = new LruCache(context);

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

// Clear cache
picassoLruCache.clear();

Keine schöne Schleife, aber dieser Ansatz hat mein Problem mit Cache und Picasso behoben.Verwenden Sie dies nur, wenn Sie den Cache für eine bestimmte URL ungültig machen möchten. Dieser Ansatz ist langsam und wahrscheinlich nicht die richtige Vorgehensweise, funktioniert aber für mich.

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

Ein sehr wichtiger Teil fehlt in der hier akzeptierten Antwort.Den Trick habe ich hier gefunden: http://blogs.candoerz.com/question/124660/android-image-cache-is-not-clearing-in-picasso.aspx

Durch einfaches Aufrufen der folgenden Zeile wird der Cache eines Fotos nicht geleert, wenn Sie beim Anzeigen des Originalbilds benutzerdefinierte Optionen wie Größenänderung, zentrierter Zuschnitt usw. verwenden.

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

Die Lösung:

Wenn Sie das Bild anzeigen, verwenden Sie stableKey() Methode.

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

Anschließend können Sie den Cache dieser Datei später leeren, indem Sie Folgendes aufrufen:

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

Ich hoffe, das wird helfen.

Sie können den Speichercache überspringen skipMemoryCache()

siehe Folgendes

        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"

Eine andere Möglichkeit besteht darin, das neue Bild in einer anderen Datei als dem Original zu speichern.Da der Picasso-Bitmap-Cache vom Dateipfad getrennt ist, führt das Laden des neuen Bildes aus einer anderen Datei zu einem Cache-Fehler.Dies hat auch den Nebenvorteil, dass nicht der gesamte Cache geleert werden muss.

verwenden shutdown() Stattdessen nach Quellcode;Durch das Herunterfahren werden keine weiteren Anfragen mehr akzeptiert und der gesamte Cache geleert

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

Sie können die Singleton-Instanz auch nicht herunterfahren.Sie benötigen also eine Instanzvariable für Picasso.Vergessen Sie nicht, die Picasso-Instanz jedes Mal neu zu initialisieren shutdown() es, um es wiederzuverwenden

File f = new File(path, name);
Picasso.with(this).invalidate(Uri.fromFile(f));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top