Entfernen Sie das Bild aus dem Cache in der Glide-Bibliothek

75

Ich verwende Glide in einem meiner Projekte, um Bilder aus Dateien anzuzeigen.

Unten ist mein Code, wie ich das Bild zeige:

Glide.with(DemoActivity.this)
     .load(Uri.parse("file://" + imagePath))
     .into(mImage);

Das Bild an dieser Stelle ( imagePath) ändert sich ständig. Standardmäßig speichert Glide das Bild im Cache ImageView. Aus diesem Grund zeigte der Glide das erste Bild aus dem Cache für neue Bilder an dieser Stelle an.

Wenn ich das Bild an der Stelle imagePathdurch ein anderes Bild mit demselben Namen ändere, zeigt der Glide das erste Bild anstelle des neuen an.

Zwei Abfragen sind:

  1. Ist es möglich, das Bild immer aus der Datei und nicht zwischenzuspeichern? Auf diese Weise wird das Problem gelöst.

  2. Ist es möglich, das Bild aus dem Cache zu löschen, bevor das neu ersetzte Bild abgerufen wird? Dies wird auch das Problem lösen.

Nitesh Kumar
quelle

Antworten:

148

So habe ich dieses Problem gelöst.

Methode 1: Wenn sich die URL ändert, wenn sich das Bild ändert

Glide.with(DemoActivity.this)
    .load(Uri.parse("file://" + imagePath))
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .skipMemoryCache(true)
    .into(mImage);

diskCacheStrategy () kann verwendet werden, um den Festplattencache zu verwalten, und Sie können den Speichercache mit der Methode skipMemoryCache () überspringen.

Methode 2: Wenn sich die URL nicht ändert, ändert sich das Bild

Wenn Ihre URL konstant bleibt, müssen Sie Signatur für den Bildcache verwenden.

Glide.with(yourFragment)
     .load(yourFileDataModel)
     .signature(new StringSignature(yourVersionMetadata))
     .into(yourImageView);

Glide Signature () bietet Ihnen die Möglichkeit, zusätzliche Daten mit dem Cache-Schlüssel zu mischen.

  • Sie können verwenden, MediaStoreSignaturewenn Sie Inhalte aus dem Medienspeicher abrufen. MediaStoreSignatureMit dieser Option können Sie das Datum, die Änderungszeit, den MIME-Typ und die Ausrichtung eines Media Store-Elements in den Cache-Schlüssel mischen. Diese drei Attribute erfassen zuverlässig Änderungen und Aktualisierungen, sodass Sie die Daumen des Medienspeichers zwischenspeichern können.
  • Sie können StringSignatureauch für Inhalte, die als Dateien gespeichert sind, die Änderungszeit des Dateidatums mischen.
Nitesh Kumar
quelle
Für mich geht das. Stellen Sie sicher, dass Sie das Bild tatsächlich ändern.
Juan José Melero Gómez
14
Beachten Sie, dass mit Glide v4 StringSignaturedurch ersetzt wurde ObjectKey, siehe Glide v4 Caching
Curly
Wenn wir bei dieser Methode dieselbe URL mit unterschiedlicher Version haben, wird dann die relavente Version geladen, wenn wir die Version übergeben?
Ishan Fernando
3
Sie haben das Problem 2 nicht gelöst. "Ist es möglich, das Bild aus dem Cache zu löschen, bevor das neu ersetzte Bild abgerufen wird? Dadurch wird auch das Problem gelöst."
Nick
1
Während es funktioniert, ist es schmerzhaft langsam, die Bilder jedes Mal mit dieser Methode zu laden
The Fluffy T Rex
55

Wie im Abschnitt Caching und Cache-Invalidierung des Glide-Wikis erläutert :

Da Dateinamen Hash-Schlüssel sind, gibt es keine gute Möglichkeit, einfach alle zwischengespeicherten Dateien auf der Festplatte zu löschen, die einer bestimmten URL oder einem bestimmten Dateipfad entsprechen. Das Problem wäre einfacher, wenn Sie nur das Originalbild laden oder zwischenspeichern könnten. Da Glide jedoch auch Miniaturansichten zwischenspeichert und verschiedene Transformationen bereitstellt, führt jede zu einer neuen Datei im Cache, die jede zwischengespeicherte Version aufspürt und löscht eines Bildes ist schwierig.

In der Praxis besteht der beste Weg, eine Cache-Datei ungültig zu machen, darin, Ihre> Kennung zu ändern, wenn sich der Inhalt ändert (URL, URL, Dateipfad usw.).

Da Sie den Dateipfad nicht ändern können, bietet Glide die Signatur () -API an, mit der Sie einige zusätzliche Daten festlegen können, die in die Speicher- und Festplatten-Cache-Schlüssel eingemischt werden sollen, sodass der Aufrufer mehr Kontrolle darüber hat, wann zwischengespeicherte Daten ungültig werden.

Wenn Sie das Image jedes Mal von der Festplatte neu laden möchten, können Sie Ihren Code folgendermaßen ändern:

Glide.with(DemoActivity.this)
     .load(Uri.parse("file://" + imagePath))
     .signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
     .into(mImage);
Mattia Maestrini
quelle
Das ist perfekt für meine Bedürfnisse. Ich habe eine Version für meine Daten. Durch einfaches Hinzufügen .signature(new StringSignature(Integer.toString(data.getVersion())))wird eine Aktualisierung der Bilder erzwungen, wenn die Version geändert wird.
Krøllebølle
@ Mattia Maestrini Danke, deine Lösung aktualisiert ein einzelnes Bild in den Cache von System.currentTimeMillis()?
DolDurma
1
Ich vermute also, dass dies das Cache-Verzeichnis nicht verschmutzt, da die URL als konstant impliziert wird, oder? Das heißt, es werden vorherige Cache-Einträge überschrieben?
TheRealChx101
für Kotlin verwenden .signature(ObjectKey(System.currentTimeMillis())))
Yonko Kilasi
35

Es gibt zwei Möglichkeiten, die Aktualisierung des Glide- Cache zu handhaben :

Erstens: - Fügen Sie unten mit Gleitimplementierung hinzu

.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)

Zweiter Weg:

Wenn Sie Bildänderungen erkennen können, geben Sie unten Ihren neuen Dateinamen an.

.signature(new StringSignature(String.valueOf(fileName)))

oder Sie möchten jedes Mal mit den neuesten Bildern laden, verwenden Sie unten

.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))

Hoffe das hilft.

Chandrahasan
quelle
32

Dadurch wird der von Glide gespeicherte Cache-Speicher entfernt. Dies sollte im Hintergrund erfolgen, da sonst eine Ausnahme ausgelöst wird

new Thread(new Runnable() {
          @Override
          public void run() {
             Glide.get(MainActivity.this).clearDiskCache();
          }
     }).start();
Anand Savjani
quelle
1
Wie wird es dann vom System entschieden, den laufenden Thread unmittelbar nach dem Löschen des Caches zu stoppen?
Yash Agrawal
1
@ YashAgrawal: Es wird durch die interne Struktur entscheiden. Also kein Grund zur Sorge
Anand Savjani
23

Hatte Probleme mit Glide 4.2.0, StringSignaturewurde nicht behoben.

Sieht so aus, als wäre StringSignaturees nicht mehr verfügbar und du musst es ObjectKeystattdessen verwenden.

Code sieht also so aus

Glide.with(imageView).
load(pathToImage).
apply(new RequestOptions().signature(new ObjectKey("signature string"))).
into(imageView);
Andrey Danilov
quelle
16

Wenn Sie Bilder unter demselben bekannten Dateinamen wie eine Konvention speichern und den Glide-Cache nur ungültig machen möchten, wenn sich die Datei geändert hat, kann die Verwendung des Zeitstempels für die Dateimodifikation gut funktionieren.

Ich habe eine solche Konvention für Avatar-Bilder verwendet, die ich auf FileObjekte außerhalb von Glide heruntergeladen habe , und dann Glide verwendet, um die Größe zu ändern und sie rund zu machen usw.

Also habe ich die StringSignatureStrategie mit dem Wert des lastChanged-Zeitstempels der Datei als Signatur verwendet. So sieht der fließende Code dafür aus:

Glide.with(this)
        .load(avatarFile)
        .diskCacheStrategy(DiskCacheStrategy.RESULT)
        .signature(new StringSignature(String.valueOf(avatarFile.lastModified())))
        .into(ivProfile);
}

wo avatarFileist mein java.io.Fileobjekt natürlich

Dhiraj Gupta
quelle
14

Ich hatte Probleme beim Festlegen der Signatur mit Glide Version 4. * mit Kotlin. Nach einiger Zeit kam ich zu folgendem Ergebnis:

fun ImageView.loadUrl(url: String) {
    var requestOptions = RequestOptions()
    requestOptions.signature(ObjectKey(System.currentTimeMillis()))
    Glide.with(this).load(url).apply(requestOptions).into(this)
}

Es ist eine Erweiterungsfunktion für ImageView und wird folgendermaßen verwendet:

 imageView.loadUrl(url)

Ich hoffe es wird jemandem helfen

Palejandro
quelle
1
genau das was ich brauche.
Anton Derevyanko
12

Für die Bibliothek Glide 4.3. + Benötigen Sie so etwas,

Glide.with(context)
    .load(image_path)
    .apply(new RequestOptions()
                        .diskCacheStrategy(DiskCacheStrategy.NONE)
                        .skipMemoryCache(true))
    .into(imge_view);
Jaydipsinh Zala
quelle
12

In den neuesten Versionen sollten wir RequestOptions verwenden

RequestOptions Bietet typunabhängige Optionen zum Anpassen von Lasten mit Glide in den neuesten Versionen von Glide.

Erstellen Sie ein RequestOptions-Objekt und verwenden Sie es, wenn wir das Bild laden.

 RequestOptions requestOptions = new RequestOptions()
                        .diskCacheStrategy(DiskCacheStrategy.NONE) // because file name is always same
                        .skipMemoryCache(true);

 Glide.with(this)
           .load(photoUrl)
           .apply(requestOptions)
           .into(profile_image);
Vinay John
quelle
6

Unterschrift mit GlideApp

    GlideApp.with(imageView)
            .load(url)
            .signature(new ObjectKey(System.currentTimeMillis()))
            .placeholder(R.drawable.sky)
            .error(R.drawable.sky)
            .into(imageView);
Dan Alboteanu
quelle
4

Das hat bei mir funktioniert

  //use  diskCacheStrategy(DiskCacheStrategy.NONE) after skipMemoryCache(true) 
         Glide.with(this)
            .load(image)
            .skipMemoryCache(true) 
            .diskCacheStrategy(DiskCacheStrategy.NONE)
            .into(imageview);
Shreyas Sanil
quelle
4

Und schließlich die Kotlin-Implementierung (For Fragments):

Glide.with(activity)
            .load(url)
            .apply(RequestOptions()
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .skipMemoryCache(true))
            .into(myImageView)
Eugene Voronoy
quelle
3

Ich habe tagelang daran gearbeitet, und alle oben genannten Lösungen sind nur langsam wie ein Faultier.

Ich weiß, dass Sie dies wahrscheinlich schon einmal gelesen und ignoriert haben, weil Sie dachten, es würde wahrscheinlich viel Arbeit kosten, Ihren Code zu ändern. Aber im Ernst, es lohnt sich. Die Leistung übertrifft, soweit ich das beurteilen kann, alle anderen vorgestellten Methoden, ist die von Glide empfohlene Lösung, UND Sie müssen weder den Cache überspringen noch Signaturen erstellen, damit auch Ihr Code sauberer bleibt.

VON Glide:

In der Praxis besteht der beste Weg , eine Cache-Datei ungültig zu machen, darin, Ihre Kennung zu ändern, wenn sich der Inhalt ändert (URL, URL, Dateipfad usw.), wenn dies möglich ist. - https://bumptech.github.io/glide/doc/caching.html

LÖSUNG: Ändern Sie den Namen des Bildes, wenn der Benutzer ein neues Bild hochlädt. Holen Sie sich den Dateinamen und verwenden Sie diesen zum Beispiel. Sobald sich die Bild-URL geändert hat, versteht Glide, dass Sie das Bild geändert haben, und aktualisiert den Cache entsprechend. Dies hat mir bei weitem die beste Leistung gebracht.

BEIM BENUTZEN:

.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)

Die Bilder werden nie zwischengespeichert, wodurch die Bilder langsam geladen werden. Sie würden denken, Signaturen sind besser für die Leistung, aber für mich schienen sie genauso langsam zu sein.

Der flauschige T Rex
quelle
1

Um den von Glide bereitgestellten Cache zu nutzen und sicherzustellen, dass jedes Mal das richtige Bild angezeigt wird, können Sie die Signatur () - API verwenden .

Sie müssen lediglich eine Information als Signatur festlegen, die sich auf die Bilddatei bezieht. Wenn Sie diese Datei ersetzen, ändern sich auch die Informationen und Glide weiß, dass sie neu geladen werden muss, wobei der Cache ignoriert wird.

Eine gültige Information könnte ein Digest (zum Beispiel SHA-1) sein, der anhand des Dateiinhalts berechnet wird.

Glide.with(context)
   .load(inputFile)
   .signature(new StringSignature(sha1(inputFile)))
   .into(targetImageView);

Hier habe ich die folgende Implementierung der Funktion sha1 () gefunden:

public static String sha1(final File file) throws NoSuchAlgorithmException, IOException {
   final MessageDigest messageDigest = MessageDigest.getInstance("SHA1");

   try (InputStream is = new BufferedInputStream(new FileInputStream(file)) {
     final byte[] buffer = new byte[1024];
     for (int read = 0; (read = is.read(buffer)) != -1;) {
       messageDigest.update(buffer, 0, read);
     }
   }

   // Convert the byte to hex format
   try (Formatter formatter = new Formatter()) {
     for (final byte b : messageDigest.digest()) {
       formatter.format("%02x", b);
     }
     return formatter.toString();
   }
}
Riccardo Leschiutta
quelle
scheint mit der Verwendung von Signatur, Diskcache und Skipmemory zusammen zu arbeiten.
Panache
1

Dieser hat für mich gearbeitet!

Glide.with(DemoActivity.this)
    .load(Uri.parse("file://" + imagePath))
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .skipMemoryCache(true)
    .into(mImage);
Allan Jaqueira
quelle
1

Ich habe Glide zum Laden von a verwendet File, und am Ende habe ich Folgendes getan, um sicherzustellen, dass der Festplatten-Cache von Glide bei jeder Änderung meiner Datei ungültig wurde (obwohl sie denselben Pfad hatte):

Glide.with(context)
    .load(bitmapFile)
    .signature(new ObjectKey(bitmapFile.lastModified()))
    .into(imageView);
Adam Johns
quelle
1
Programmatically simply you can use,

 Glide.get(getApplicationContext()).clearMemory();
 Glide.get(getApplicationContext()).clearDiskCache();

Für mehr

Fragen Sie Shiwa
quelle
0

1) Löschen Sie zuerst den Festplatten- Cache.

private class ClearGlideCacheAsyncTask extends AsyncTask<Void, Void, Boolean>{

        private boolean result;

        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                Glide.get(getContext()).clearDiskCache();
                result = true;
            }
            catch (Exception e){
            }
            return result;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if(result)
                Toast.makeText(getActivity(), "cache deleted", Toast.LENGTH_SHORT).show();
        }
    }

Sie können von Ihrer Benutzeroberfläche aus mit anrufen new ClearGlideCacheAsyncTask ().execute();

2) Speichercache löschen

// This method must be called on the main thread.
Glide.get(context).clearMemory();

Quelle: https://bumptech.github.io/glide/doc/caching.html

Zhar
quelle