Wie kann ich Bilder in den Cache stellen, nachdem sie aus dem Internet heruntergeladen wurden?
Antworten
Zu viele Anzeigen?Und nun 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, der gemeinsam mit dem Browser genutzt wird.
grr. Ich wünschte, jemand hätte mir das gesagt, bevor ich meinen eigenen Cache-Manager geschrieben habe.
Bezüglich der eleganten connection.setUseCaches
Lösung oben: Leider wird es nicht ohne zusätzlichen Aufwand funktionieren. Sie müssen ein ResponseCache
mit ResponseCache.setDefault
. Ansonsten, HttpURLConnection
ignoriert stillschweigend die setUseCaches(true)
etwas.
Siehe die Kommentare am Anfang der Seite FileResponseCache.java
für Details:
(Ich würde das in einem Kommentar posten, aber ich habe anscheinend nicht genug SO-Karma).
Konvertieren Sie sie in Bitmaps und speichern Sie sie dann entweder in einer Sammlung (HashMap, Liste usw.) oder schreiben Sie sie auf die SD-Karte.
Wenn Sie sie mit dem ersten Ansatz im Anwendungsbereich speichern, sollten Sie sie um eine java.lang.ref.SoftReference insbesondere wenn ihre Anzahl groß ist (so dass sie in Krisenzeiten in den Müll wandern). Dies könnte allerdings ein Reload zur Folge haben.
HashMap<String,SoftReference<Bitmap>> imageCache =
new HashMap<String,SoftReference<Bitmap>>();
Um sie auf die SD-Karte zu schreiben, ist kein Reload erforderlich, sondern nur eine Benutzererlaubnis.
Utilice LruCache
um Bilder effizient zwischenzuspeichern. Sie können lesen über LruCache
von Android-Entwickler-Website
Ich habe die folgende Lösung für das Herunterladen und Zwischenspeichern von Bildern in Android verwendet. Sie können Schritte unten folgen:
SCHRITT 1: make Class Named ImagesCache
. Ich habe verwendet Singleton object for this class
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class ImagesCache
{
private LruCache<String, Bitmap> imagesWarehouse;
private static ImagesCache cache;
public static ImagesCache getInstance()
{
if(cache == null)
{
cache = new ImagesCache();
}
return cache;
}
public void initializeCache()
{
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() /1024);
final int cacheSize = maxMemory / 8;
System.out.println("cache size = "+cacheSize);
imagesWarehouse = new LruCache<String, Bitmap>(cacheSize)
{
protected int sizeOf(String key, Bitmap value)
{
// The cache size will be measured in kilobytes rather than number of items.
int bitmapByteCount = value.getRowBytes() * value.getHeight();
return bitmapByteCount / 1024;
}
};
}
public void addImageToWarehouse(String key, Bitmap value)
{
if(imagesWarehouse != null && imagesWarehouse.get(key) == null)
{
imagesWarehouse.put(key, value);
}
}
public Bitmap getImageFromWarehouse(String key)
{
if(key != null)
{
return imagesWarehouse.get(key);
}
else
{
return null;
}
}
public void removeImageFromWarehouse(String key)
{
imagesWarehouse.remove(key);
}
public void clearCache()
{
if(imagesWarehouse != null)
{
imagesWarehouse.evictAll();
}
}
}
SCHRITT 2:
eine weitere Klasse mit dem Namen DownloadImageTask erstellen, die verwendet wird, wenn die Bitmap nicht im Cache vorhanden ist, wird sie von hier heruntergeladen:
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap>
{
private int inSampleSize = 0;
private String imageUrl;
private BaseAdapter adapter;
private ImagesCache cache;
private int desiredWidth, desiredHeight;
private Bitmap image = null;
private ImageView ivImageView;
public DownloadImageTask(BaseAdapter adapter, int desiredWidth, int desiredHeight)
{
this.adapter = adapter;
this.cache = ImagesCache.getInstance();
this.desiredWidth = desiredWidth;
this.desiredHeight = desiredHeight;
}
public DownloadImageTask(ImagesCache cache, ImageView ivImageView, int desireWidth, int desireHeight)
{
this.cache = cache;
this.ivImageView = ivImageView;
this.desiredHeight = desireHeight;
this.desiredWidth = desireWidth;
}
@Override
protected Bitmap doInBackground(String... params)
{
imageUrl = params[0];
return getImage(imageUrl);
}
@Override
protected void onPostExecute(Bitmap result)
{
super.onPostExecute(result);
if(result != null)
{
cache.addImageToWarehouse(imageUrl, result);
if(ivImageView != null)
{
ivImageView.setImageBitmap(result);
}
else if(adapter != null)
{
adapter.notifyDataSetChanged();
}
}
}
private Bitmap getImage(String imageUrl)
{
if(cache.getImageFromWarehouse(imageUrl) == null)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = inSampleSize;
try
{
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
InputStream stream = connection.getInputStream();
image = BitmapFactory.decodeStream(stream, null, options);
int imageWidth = options.outWidth;
int imageHeight = options.outHeight;
if(imageWidth > desiredWidth || imageHeight > desiredHeight)
{
System.out.println("imageWidth:"+imageWidth+", imageHeight:"+imageHeight);
inSampleSize = inSampleSize + 2;
getImage(imageUrl);
}
else
{
options.inJustDecodeBounds = false;
connection = (HttpURLConnection)url.openConnection();
stream = connection.getInputStream();
image = BitmapFactory.decodeStream(stream, null, options);
return image;
}
}
catch(Exception e)
{
Log.e("getImage", e.toString());
}
}
return image;
}
SCHRITT 3: Nutzung von Ihrem Activity
o Adapter
Nota: Wenn Sie ein Bild aus einer Url laden möchten, die von Activity
Klasse. Verwenden Sie den zweiten Konstruktor von DownloadImageTask
, aber wenn Sie ein Bild aus Adapter
verwenden Sie den ersten Constructor von DownloadImageTask
(zum Beispiel haben Sie ein Bild in ListView
und Sie setzen das Bild von 'Adapter')
NUTZUNG AUS AKTIVITÄT:
ImageView imv = (ImageView) findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();//Singleton instance handled in ImagesCache class.
cache.initializeCache();
String img = "your_image_url_here";
Bitmap bm = cache.getImageFromWarehouse(img);
if(bm != null)
{
imv.setImageBitmap(bm);
}
else
{
imv.setImageBitmap(null);
DownloadImageTask imgTask = new DownloadImageTask(cache, imv, 300, 300);//Since you are using it from `Activity` call second Constructor.
imgTask.execute(img);
}
VERWENDUNG VOM ADAPTER:
ImageView imv = (ImageView) rowView.findViewById(R.id.imageView);
ImagesCache cache = ImagesCache.getInstance();
cache.initializeCache();
String img = "your_image_url_here";
Bitmap bm = cache.getImageFromWarehouse(img);
if(bm != null)
{
imv.setImageBitmap(bm);
}
else
{
imv.setImageBitmap(null);
DownloadImageTask imgTask = new DownloadImageTask(this, 300, 300);//Since you are using it from `Adapter` call first Constructor.
imgTask.execute(img);
}
Nota:
cache.initializeCache()
können Sie diese Aussage in der allerersten Aktivität Ihrer Bewerbung verwenden. Sobald Sie den Cache initialisiert haben, müssen Sie ihn nicht jedes Mal neu initialisieren, wenn Sie ImagesCache
Instanz.
Ich bin nie gut darin, Dinge zu erklären, aber ich hoffe, dass dies den Anfängern helfen wird, wie man den Cache mit LruCache
und seine Verwendung :)
EDIT :
Heutzutage gibt es sehr berühmte Bibliotheken, die als Picasso
y Glide
die zum sehr effizienten Laden von Bildern in einer Android-App verwendet werden kann. Probieren Sie diese sehr einfache und nützliche Bibliothek aus Picasso für Android y Gleiten für Android . Sie brauchen sich nicht um Cache-Bilder zu kümmern.
Picasso ermöglicht müheloses in einer einzigen Code-Zeile!
Glide, genau wie Picasso, kann Quellen laden und anzeigen, während es gleichzeitig für die Zwischenspeicherung und einen geringen Speicherbedarf sorgt. bei Bildmanipulationen. Es wurde verwendet von offiziellen Google-Apps verwendet (wie die App für die Google I/O 2015) und ist genauso beliebt wie wie Picasso. In dieser Serie werden wir die Unterschiede und Vorteile von Glide gegenüber Picasso.
Sie können auch den Blog besuchen für Unterschied zwischen Glide und Picasso
Um ein Bild herunterzuladen und auf der Speicherkarte zu speichern, können Sie wie folgt vorgehen.
//First create a new URL object
URL url = new URL("http://www.google.co.uk/logos/holiday09_2.gif")
//Next create a file, the example below will save to the SDCARD using JPEG format
File file = new File("/sdcard/example.jpg");
//Next create a Bitmap object and download the image to bitmap
Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());
//Finally compress the bitmap, saving to the file previously created
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(file));
Vergessen Sie nicht, die Interneterlaubnis zu Ihrem Manifest hinzuzufügen:
<uses-permission android:name="android.permission.INTERNET" />
- See previous answers
- Weitere Antworten anzeigen