Android image cache implementation, especially suitable for listview scrolling back and forth

转载自:
http://www.open-open.com/lib/view/open1384349254555.html
缓存类就一个:
AsyncBitmapLoader
package com.ikuaishou.kuaishou.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.widget.ImageView;

import com.ikuaishou.kuaishou.R;

public class AsyncBitmapLoader {

// To speed up, enable cache in memory (mainly used for repetition When there are many pictures, or the same picture needs to be accessed multiple times, such as scrolling back and forth in ListView)
public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
private ExecutorService executorService = Executors.newFixedThreadPool(5); // Fix five threads to execute tasks
private final Handler handler = new Handler();
// Picture storage address on SD card
private final String path = Environment.getExternalStorageDirectory()
.getPath() + " /ikuaishou";

/**
*
* @param imageUrl
* image url address
* @param callback
* Callback interface
* @return Returns the image cached in memory, null is returned for the first load
*/
public Drawable loadDrawable(final String imageUrl,
final ImageCallback callback) {
// If the cache is over, get the data from the cache
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
} else if (useTheImage(imageUrl) != null) {
return useTheImage(imageUrl);
}
// If there is no image in the cache, retrieve the data from the network and cache the retrieved data in memory
executorService.submit(new Runnable() {
public void run() {
try {
final Drawable drawable = Drawable.createFromStream(
new URL(imageUrl).openStream(), "image.png");
imageCache.put(imageUrl, new SoftReference<Drawable>(
drawable));
handler.post(new Runnable() {
public void run() {
callback.imageLoaded(drawable);
}
});
saveFile(drawable, imageUrl);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return null;
}

// 从网络上取数据方法
public Drawable loadImageFromUrl(String imageUrl) {
try {

return Drawable.createFromStream(new URL(imageUrl).openStream(),
"image.png");
} catch (Exception e) {
throw new RuntimeException(e);
}
}

// Callback interface open to the outside world
public interface ImageCallback {
// Note that this method is used to set the image resource of the target object
public void imageLoaded(Drawable imageDrawable);
}

// Introduce the thread pool, introduce the memory cache function, and encapsulate the interface for external calls to simplify the calling process
public void LoadImage(final String url, final ImageView iv) {
if (iv.getImageMatrix() == null) {
iv .setImageResource(R.drawable.headimgurl);
}
// If the image is cached, the image will be taken from the cache, and the method in the ImageCallback interface will not be executed
Drawable cacheImage = loadDrawable(url,new ImageCallback() {

@Override
public void imageLoaded (Drawable imageDrawable) {
iv.setImageDrawable(imageDrawable);
}
});
if (cacheImage != null) {
iv.setImageDrawable(cacheImage);
}
}

/**
* Save image to SD card
*
* @param bm
* @param fileName
*
*/
public void saveFile(Drawable dw, String url) {
try {
BitmapDrawable bd = (BitmapDrawable) dw;
Bitmap bm = bd.getBitmap();

// get the file name
final String fileNa = url.substring(url.lastIndexOf("/") + 1,
url.length ()).toLowerCase();
File file = new File(path + "/image/" + fileNa);
// Create image cache folder
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED); // Determine if the sd card exists
if (sdCardExist) {
File maiduo = new File(path);
File ad = new File(path + "/image");
// If the folder does not exist exists
if (!maiduo.exists()) {
// create a folder according to the specified path
maiduo.mkdir();
// if the folder does not exist
} else if (!ad.exists()) {
// according to the specified path Path to create folder
ad.mkdir();
}
// Check if image exists
if (!file.exists()) {
file.createNewFile();
}
}

BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
bm. compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
} catch (Exception e) {
// TODO: handle exception
}
}

/**
* Use image from SD card
*
*/
public Drawable useTheImage(String imageUrl) {

Bitmap bmpDefaultPic = null;

// Get file path
String imageSDCardPath = path
+ "/image/"
+ imageUrl.substring(imageUrl.lastIndexOf("/") + 1,
imageUrl.length()).toLowerCase();
File file = new File(imageSDCardPath);
// Check if the image exists
if ( !file.exists()) {
return null;
}
bmpDefaultPic = BitmapFactory.decodeFile(imageSDCardPath, null);

if (bmpDefaultPic != null || bmpDefaultPic.toString().length() > 3) {
Drawable drawable = new BitmapDrawable(bmpDefaultPic);
return drawable;
} else
return null;
}
}


使用很简单:
asyncBitmapLoader.LoadImage(list.get(position).getPic(), holder.iv_pic);

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326662318&siteId=291194637