Comment puis-je mettre en cache des images après leur téléchargement sur le Web?
141
Et maintenant la punchline: utilisez le cache système.
URL url = new URL(strUrl);
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
}
Fournit à la fois de la mémoire et un cache flash-rom, partagés avec le navigateur.
grr. J'aurais aimé que quelqu'un ME dise cela avant d'écrire mon propre gestionnaire de cache.
connection.getContent()
renvoie toujours un InputStream pour moi, qu'est-ce que je fais de mal?Bitmap response = BitmapFactory.decodeStream((InputStream)connection.getContent());
En ce qui concerne la
connection.setUseCaches
solution élégante ci-dessus: malheureusement, cela ne fonctionnera pas sans un effort supplémentaire. Vous devrez installer un fichierResponseCache
usingResponseCache.setDefault
. Sinon,HttpURLConnection
ignorera silencieusement lesetUseCaches(true)
bit.Voir les commentaires en haut de
FileResponseCache.java
pour plus de détails:http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(Je publierais ceci dans un commentaire, mais je n'ai apparemment pas assez de karma SO.)
la source
HttpResponseCache
, vous pouvez trouver leHttpResponseCache.getHitCount()
retour 0. Je ne suis pas sûr mais je pense que c'est parce que le serveur Web que vous demandez n'utilise pas les en-têtes de mise en cache dans ce cas. Pour que la mise en cache fonctionne de toute façon, utilisezconnection.addRequestProperty("Cache-Control", "max-stale=" + MAX_STALE_CACHE);
..getContent()
méthode car les réponses 304 n'ont pas de corps de réponse associé par la norme RFC.Convertissez-les en bitmaps, puis stockez-les dans une collection (HashMap, liste, etc.) ou vous pouvez les écrire sur la carte SD.
Lorsque vous les stockez dans l'espace d'application en utilisant la première approche, vous voudrez peut-être les enrouler autour d'un java.lang.ref.SoftReference spécifiquement si leur nombre est grand (afin qu'ils soient ramassés pendant la crise). Cela pourrait cependant entraîner un rechargement.
les écrire sur la carte SD ne nécessitera pas de rechargement; juste une permission d'utilisateur.
la source
Uri
référence de chemin à laquelle vous pouvez passerImageView
et d'autres vues personnalisées. Parce qu'à chaque foiscompress
, vous perdrez de la qualité. Bien sûr, cela n'est vrai que pour les algorithmes avec perte. Cette méthode vous permettrait également de stocker même un hachage du fichier et de l'utiliser la prochaine fois que vous demanderez le fichier au serveur viaIf-None-Match
et les en-ETag
têtes.Utilisez
LruCache
pour mettre en cache les images efficacement. Vous pouvez lire àLruCache
partir de Android site développeurJ'ai utilisé la solution ci-dessous pour le téléchargement d'images et la mise en cache dans Android. Vous pouvez suivre les étapes ci-dessous:
ÉTAPE 1: créez la classe nommée
ImagesCache
. J'ai utiliséSingleton object for this class
ÉTAPE 2:
créez une autre classe nommée DownloadImageTask qui est utilisée si le bitmap n'est pas disponible dans le cache, il le téléchargera à partir d'ici:
ÉTAPE 3: Utilisation depuis votre
Activity
ouAdapter
Remarque: si vous souhaitez charger une image à partir de l'URL de
Activity
Class. Utilisez le deuxième constructeur deDownloadImageTask
, mais si vous souhaitez afficher l'image à partir duAdapter
premier constructeur deDownloadImageTask
(par exemple, vous avez une image dansListView
et vous définissez l'image à partir de 'Adapter')UTILISATION DE L'ACTIVITÉ:
UTILISATION DE L'ADAPTATEUR:
Remarque:
cache.initializeCache()
vous pouvez utiliser cette instruction dans la toute première activité de votre application. Une fois que vous avez initialisé le cache, vous n'aurez jamais besoin de l'initialiser à chaque fois si vous utilisezImagesCache
instance.Je ne suis jamais doué pour expliquer les choses mais j'espère que cela aidera les débutants à savoir comment mettre en cache l'utilisation
LruCache
et son utilisation :)ÉDITER:
Aujourd'hui, il existe des bibliothèques très célèbres connues sous le nom de
Picasso
etGlide
qui peuvent être utilisées pour charger des images très efficacement dans l'application Android. Essayez cette bibliothèque très simple et utile Picasso pour Android et Glide pour Android . Vous n'avez pas à vous soucier des images de cache.Vous pouvez également visiter le blog pour la différence entre Glide et Picasso
la source
if(cache == null)
qui a résolu mon problème! :)Pour télécharger une image et l'enregistrer sur la carte mémoire, vous pouvez le faire comme ceci.
N'oubliez pas d'ajouter l'autorisation Internet à votre manifeste:
la source
J'envisagerais d'utiliser le cache d'image de droidfu. Il implémente à la fois un cache d'image en mémoire et sur disque. Vous obtenez également un WebImageView qui tire parti de la bibliothèque ImageCache.
Voici la description complète de droidfu et WebImageView: http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
la source
J'ai essayé SoftReferences, ils sont récupérés de manière trop agressive dans Android que je sentais qu'il ne servait à rien de les utiliser
la source
SoftReference
art. Ils recommandent d'utiliser leur à laLruCache
place.Comme l'a suggéré Thunder Rabbit, ImageDownloader est le meilleur pour le travail. J'ai également trouvé une légère variation de la classe à:
http://theandroidcoder.com/utilities/android-image-download-and-caching/
La principale différence entre les deux est que ImageDownloader utilise le système de mise en cache Android et que celui modifié utilise le stockage interne et externe comme mise en cache, conservant les images en cache indéfiniment ou jusqu'à ce que l'utilisateur le supprime manuellement. L'auteur mentionne également la compatibilité Android 2.1.
la source
C'est une bonne prise de Joe. L'exemple de code ci-dessus a deux problèmes - un - l'objet de réponse n'est pas une instance de Bitmap (lorsque mon URL fait référence à un jpg, comme http: \ website.com \ image.jpg, c'est un
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl $ LimitedInputStream).
Deuxièmement, comme le souligne Joe, aucune mise en cache n'a lieu sans la configuration d'un cache de réponse. Les développeurs Android doivent rouler leur propre cache. Voici un exemple pour le faire, mais cela ne met en cache que la mémoire, ce qui n'est vraiment pas la solution complète.
http://codebycoffee.com/2010/06/29/using-responsecache-in-an-android-app/
L'API de mise en cache URLConnection est décrite ici:
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-cache.html
Je pense toujours que c'est une bonne solution pour suivre cette voie - mais vous devez toujours écrire un cache. Cela semble amusant, mais je préfère écrire des fonctionnalités.
la source
Il y a une entrée spéciale dans la section de formation officielle d'Android à ce sujet: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
La section est assez récente, elle n'était pas là lorsque la question a été posée.
La solution suggérée est d'utiliser un LruCache. Cette classe a été introduite sur Honeycomb, mais elle est également incluse dans la bibliothèque de compatibilité.
Vous pouvez initialiser un LruCache en définissant le nombre maximum d'entrées et il les triera automatiquement à votre guise et les nettoiera les moins utilisées lorsque vous dépassez la limite. Autre que cela, il est utilisé comme une carte normale.
L'exemple de code de la page officielle:
Auparavant, SoftReferences était une bonne alternative, mais plus maintenant, citant la page officielle:
la source
Envisagez d'utiliser la bibliothèque Universal Image Loader de Sergey Tarasevich . Il est livré avec:
Universal Image Loader permet une gestion détaillée du cache pour les images téléchargées, avec les configurations de cache suivantes:
UsingFreqLimitedMemoryCache
: Le bitmap le moins fréquemment utilisé est supprimé lorsque la limite de taille du cache est dépassée.LRULimitedMemoryCache
: Le bitmap le moins récemment utilisé est supprimé lorsque la limite de taille du cache est dépassée.FIFOLimitedMemoryCache
: La règle FIFO est utilisée pour la suppression lorsque la limite de taille du cache est dépassée.LargestLimitedMemoryCache
: Le bitmap le plus grand est supprimé lorsque la limite de taille du cache est dépassée.LimitedAgeMemoryCache
: L'objet mis en cache est supprimé lorsque son âge dépasse la valeur définie .WeakMemoryCache
: Un cache mémoire avec uniquement des références faibles aux bitmaps.Un exemple d'utilisation simple:
Cet exemple utilise la valeur par défaut
UsingFreqLimitedMemoryCache
.la source
Ce qui a réellement fonctionné pour moi a été de définir ResponseCache sur ma classe Main:
et
lors du téléchargement de bitmap.
http://practicaldroid.blogspot.com/2013/01/utilizing-http-response-cache.html
la source
Les libs-for-android de Google ont de belles bibliothèques pour gérer le cache d'images et de fichiers.
http://code.google.com/p/libs-for-android/
la source
J'avais lutté avec ça depuis un certain temps; les réponses utilisant SoftReferences perdraient leurs données trop rapidement. Les réponses qui suggèrent d'instancier un RequestCache étaient trop compliquées et je n'ai jamais pu trouver d'exemple complet.
Mais ImageDownloader.java fonctionne à merveille pour moi. Il utilise un HashMap jusqu'à ce que la capacité soit atteinte ou jusqu'à ce que le délai de purge se produise, puis les choses sont déplacées vers une SoftReference, utilisant ainsi le meilleur des deux mondes.
la source
Je suggère IGNITION c'est encore mieux que Droid fu
https://github.com/kaeppler/ignition
https://github.com/kaeppler/ignition/wiki/Sample-applications
la source
Réponse encore plus tardive, mais j'ai écrit un gestionnaire d'images Android qui gère la mise en cache de manière transparente (mémoire et disque). Le code est sur Github https://github.com/felipecsl/Android-ImageManager
la source
Réponse tardive, mais je me suis dit que je devrais ajouter un lien vers mon site car j'ai écrit un tutoriel sur la création d'un cache d'image pour Android:
http://squarewolf.nl/2010/11/android-image-cache/Mise à jour: le La page a été mise hors ligne car la source était obsolète. Je rejoins @elenasys dans ses conseils d'utilisation d' Ignition .Alors à toutes les personnes qui tombent sur cette question et n'ont pas trouvé de solution: j'espère que vous apprécierez! = D
la source
Réponse tardive mais je pense que cette bibliothèque aidera beaucoup avec la mise en cache des images: https://github.com/crypticminds/ColdStorage .
Annotez simplement l'ImageView avec @LoadCache (R.id.id_of_my_image_view, "URL_to_downlaod_image_from) et il se chargera de télécharger l'image et de la charger dans la vue d'image. Vous pouvez également spécifier une image d'espace réservé et charger l'animation.
Une documentation détaillée de l'annotation est présente ici: - https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation
la source