Wie kann ich Bilder zwischenspeichern, nachdem sie aus dem Internet heruntergeladen wurden?
141
Und jetzt die Pointe: Verwenden Sie den System-Cache.
URL url = new URL(strUrl);
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
}
Bietet sowohl Speicher als auch Flash-ROM-Cache, die für den Browser freigegeben sind.
grr. Ich wünschte, jemand hätte mir das gesagt, bevor ich meinen eigenen Cache-Manager schrieb.
connection.getContent()
Gibt immer einen InputStream für mich zurück. Was mache ich falsch?Bitmap response = BitmapFactory.decodeStream((InputStream)connection.getContent());
In Bezug auf die elegante
connection.setUseCaches
Lösung oben: Leider funktioniert es nicht ohne zusätzlichen Aufwand. Sie müssen eineResponseCache
using installierenResponseCache.setDefault
. AndernfallsHttpURLConnection
wird dassetUseCaches(true)
Bit stillschweigend ignoriert .Weitere
FileResponseCache.java
Informationen finden Sie in den Kommentaren oben auf:http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(Ich würde dies in einem Kommentar posten, aber ich habe anscheinend nicht genug SO-Karma.)
quelle
HttpResponseCache
, finden Sie möglicherweise dieHttpResponseCache.getHitCount()
Rückgabe 0. Ich bin nicht sicher, aber ich denke, das liegt daran, dass der von Ihnen angeforderte Webserver in diesem Fall keine Caching-Header verwendet. Verwenden Sie, um das Caching trotzdem zum Laufen zu bringenconnection.addRequestProperty("Cache-Control", "max-stale=" + MAX_STALE_CACHE);
..getContent()
Methode verwendet wird, da 304 Antworten nach RFC-Standard kein Antworttext zugeordnet ist.Konvertieren Sie sie in Bitmaps und speichern Sie sie entweder in einer Sammlung (HashMap, Liste usw.) oder Sie können sie auf die SD-Karte schreiben.
Wenn Sie sie mit dem ersten Ansatz im Anwendungsbereich speichern, möchten Sie sie möglicherweise um eine java.lang.ref.SoftReference wickeln, insbesondere wenn ihre Anzahl groß ist (damit sie während der Krise als Müll gesammelt werden). Dies könnte jedoch zu einem Neuladen führen.
Für das Schreiben auf eine SD-Karte ist kein erneutes Laden erforderlich. nur eine Benutzerberechtigung.
quelle
Uri
Pfadreferenz zu erhalten, an die Sie übergeben können,ImageView
sowie andere benutzerdefinierte Ansichten. Denn jedes Malcompress
verlieren Sie an Qualität. Dies gilt natürlich nur für verlustbehaftete Algorithmen. Mit dieser Methode können Sie auch einen Hash der Datei speichern und beim nächsten Anfordern der Datei vom Server überIf-None-Match
und in denETag
Headern verwenden.Verwenden Sie
LruCache
diese Option, um Bilder effizient zwischenzuspeichern. Sie können überLruCache
von Android Developer Site lesenIch habe unten Lösung für das Herunterladen und Zwischenspeichern von Bildern in Android verwendet. Sie können die folgenden Schritte ausführen:
SCHRITT 1: Klasse benennen
ImagesCache
. Ich habe benutztSingleton object for this class
SCHRITT 2:
Erstellen Sie eine andere Klasse mit dem Namen DownloadImageTask, die verwendet wird, wenn die Bitmap nicht im Cache verfügbar ist. Sie wird von hier heruntergeladen:
SCHRITT 3: Verwendung von Ihrem
Activity
oderAdapter
Hinweis: Wenn Sie ein Bild von einer URL aus der
Activity
Klasse laden möchten . Verwenden Sie den zweiten Konstruktor vonDownloadImageTask
, aber wenn Sie ein Bild anzeigen möchten,Adapter
verwenden Sie den ersten Konstruktor vonDownloadImageTask
(zum Beispiel haben Sie ein Bild inListView
und setzen das Bild von 'Adapter').NUTZUNG AUS DER AKTIVITÄT:
VERWENDUNG VOM ADAPTER:
Hinweis:
cache.initializeCache()
Sie können diese Anweisung in der allerersten Aktivität Ihrer Anwendung verwenden. Sobald Sie den Cache initialisiert haben, müssen Sie ihn nie mehr jedes Mal initialisieren, wenn Sie eineImagesCache
Instanz verwenden.Ich bin nie gut darin, Dinge zu erklären, aber ich hoffe, dies wird den Anfängern helfen, wie man die Verwendung
LruCache
und ihre Verwendung zwischenspeichert :)BEARBEITEN:
Heute gibt es sehr berühmte Bibliotheken, die als
Picasso
und bekanntGlide
sind, um Bilder sehr effizient in Android App zu laden. Probieren Sie diese sehr einfache und nützliche Bibliothek Picasso für Android und Glide für Android . Sie müssen sich keine Gedanken über Cache-Bilder machen.Sie können auch den Blog besuchen, um den Unterschied zwischen Glide und Picasso zu erfahren
quelle
if(cache == null)
was mein Problem gelöst hat! :)Um ein Bild herunterzuladen und auf der Speicherkarte zu speichern, können Sie dies folgendermaßen tun.
Vergessen Sie nicht, Ihrem Manifest die Internetberechtigung hinzuzufügen:
quelle
Ich würde in Betracht ziehen, den Bildcache von droidfu zu verwenden. Es implementiert sowohl einen speicherinternen als auch einen festplattenbasierten Image-Cache. Sie erhalten auch eine WebImageView, die die ImageCache-Bibliothek nutzt.
Hier ist die vollständige Beschreibung von droidfu und WebImageView: http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
quelle
Ich habe SoftReferences ausprobiert, sie werden in Android zu aggressiv zurückgefordert, als dass ich der Meinung wäre, dass es keinen Sinn macht, sie zu verwenden
quelle
SoftReference
s sehr aggressiv ist . Sie empfehlen stattdessen ihreLruCache
.Wie Thunder Rabbit vorgeschlagen hat, ist ImageDownloader der beste für diesen Job. Ich fand auch eine leichte Variation der Klasse bei:
http://theandroidcoder.com/utilities/android-image-download-and-caching/
Der Hauptunterschied zwischen beiden besteht darin, dass der ImageDownloader das Android-Caching-System verwendet und der modifizierte den internen und externen Speicher als Caching verwendet, wobei die zwischengespeicherten Bilder unbegrenzt bleiben oder bis der Benutzer sie manuell entfernt. Der Autor erwähnt auch die Kompatibilität mit Android 2.1.
quelle
Dies ist ein guter Fang von Joe. Das obige Codebeispiel hat zwei Probleme - eines - das Antwortobjekt ist keine Instanz von Bitmap (wenn meine URL auf ein JPG verweist, wie z. B. http: \ website.com \ image.jpg, ist es ein
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl $ LimitedInputStream).
Zweitens, wie Joe betont, findet kein Caching statt, ohne dass ein Antwortcache konfiguriert ist. Android-Entwickler müssen ihren eigenen Cache rollen. Hier ist ein Beispiel dafür, aber es werden nur im Speicher zwischengespeichert, was wirklich nicht die vollständige Lösung ist.
http://codebycoffee.com/2010/06/29/using-responsecache-in-an-android-app/
Die URLConnection-Caching-API wird hier beschrieben:
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-cache.html
Ich denke immer noch, dass dies eine gute Lösung ist, um diesen Weg zu gehen - aber Sie müssen immer noch einen Cache schreiben. Klingt nach Spaß, aber ich würde lieber Features schreiben.
quelle
Es gibt einen speziellen Eintrag im offiziellen Trainingsbereich von Android dazu: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Der Abschnitt ist ziemlich neu, er war nicht da, als die Frage gestellt wurde.
Die vorgeschlagene Lösung ist die Verwendung eines LruCache. Diese Klasse wurde in Honeycomb eingeführt, ist aber auch in der Kompatibilitätsbibliothek enthalten.
Sie können einen LruCache initialisieren, indem Sie die maximale Anzahl oder die maximalen Einträge festlegen. Diese sortieren sie automatisch nach Ihren Wünschen und bereinigen weniger verwendete Einträge, wenn Sie das Limit überschreiten. Ansonsten wird es als normale Karte verwendet.
Der Beispielcode von der offiziellen Seite:
Bisher waren SoftReferences eine gute Alternative, aber nicht mehr, zitiert von der offiziellen Seite:
quelle
Erwägen Sie die Verwendung der Universal Image Loader-Bibliothek von Sergey Tarasevich . Es kommt mit:
Universal Image Loader ermöglicht eine detaillierte Cache-Verwaltung für heruntergeladene Bilder mit den folgenden Cache-Konfigurationen:
UsingFreqLimitedMemoryCache
: Die am seltensten verwendete Bitmap wird gelöscht, wenn die Cache-Größenbeschränkung überschritten wird.LRULimitedMemoryCache
: Das zuletzt verwendete Bitmap wird gelöscht, wenn die Cache-Größenbeschränkung überschritten wird.FIFOLimitedMemoryCache
: Die FIFO-Regel wird zum Löschen verwendet, wenn die Cache-Größenbeschränkung überschritten wird.LargestLimitedMemoryCache
: Das größte Bitmap wird gelöscht, wenn die Cache-Größenbeschränkung überschritten wird.LimitedAgeMemoryCache
: Das zwischengespeicherte Objekt wird gelöscht, wenn es Alter den definierten Wert überschreitet .WeakMemoryCache
: Ein Speichercache mit nur schwachen Verweisen auf Bitmaps.Ein einfaches Anwendungsbeispiel:
In diesem Beispiel wird die Standardeinstellung verwendet
UsingFreqLimitedMemoryCache
.quelle
Was für mich tatsächlich funktionierte, war das Festlegen von ResponseCache für meine Hauptklasse:
und
beim Herunterladen der Bitmap.
http://practicaldroid.blogspot.com/2013/01/utilizing-http-response-cache.html
quelle
Googles libs-for-android verfügt über nette Bibliotheken zum Verwalten des Bild- und Dateicaches.
http://code.google.com/p/libs-for-android/
quelle
Ich hatte seit einiger Zeit damit gerungen; Die Antworten mit SoftReferences würden ihre Daten zu schnell verlieren. Die Antworten, die darauf hindeuten, einen RequestCache zu instanziieren, waren zu chaotisch, und ich konnte nie ein vollständiges Beispiel finden.
Aber ImageDownloader.java funktioniert wunderbar für mich. Es wird eine HashMap verwendet, bis die Kapazität erreicht ist oder bis das Zeitlimit für die Bereinigung auftritt. Anschließend werden die Dinge in eine SoftReference verschoben, wodurch das Beste aus beiden Welten verwendet wird.
quelle
Ich schlage ZÜNDUNG vor, dies ist sogar besser als Droid Fu
https://github.com/kaeppler/ignition
https://github.com/kaeppler/ignition/wiki/Sample-applications
quelle
Noch später antworten, aber ich habe einen Android Image Manager geschrieben, der das Caching transparent (Speicher und Festplatte) handhabt. Der Code befindet sich auf Github https://github.com/felipecsl/Android-ImageManager
quelle
Späte Antwort, aber ich dachte mir, ich sollte einen Link zu meiner Site hinzufügen, da ich ein Tutorial geschrieben habe, wie man einen Bildcache für Android erstellt:
http://squarewolf.nl/2010/11/android-image-cache/Update: the Die Seite wurde offline geschaltet, da die Quelle veraltet war. Ich schließe mich @elenasys in ihrem Rat an, Ignition zu verwenden .Also an alle Leute, die über diese Frage stolpern und keine Lösung gefunden haben: Ich hoffe es gefällt euch! = D.
quelle
Späte Antwort, aber ich denke, diese Bibliothek wird beim Zwischenspeichern von Bildern sehr hilfreich sein: https://github.com/crypticminds/ColdStorage .
Kommentieren Sie die ImageView einfach mit @LoadCache (R.id.id_of_my_image_view, "URL_to_downlaod_image_from"). Das Bild wird heruntergeladen und in die Bildansicht geladen. Sie können auch ein Platzhalterbild angeben und eine Animation laden.
Eine ausführliche Dokumentation der Anmerkung finden Sie hier: - https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation
quelle