在android中ListView使用得很多,而且经常会显示一些图片,这些图片要么要从网上下载,要不就要处理一下本地的图片,产生一个缩略图。为了避免ANR和OOM,创建一个工具类,使用二级缓存来异步加载图片。
-
public class CacheImageLoader {
-
-
// 缓存的大小
-
-
private static final int MAX_CAPACITY = 15;
-
// 二级缓存
-
-
private static ConcurrentHashMap<String, SoftReference<Drawable>> mSoftCache = new ConcurrentHashMap<String, SoftReference<Drawable>>(
-
MAX_CAPACITY / 2);
-
// 一级缓存
-
-
private static HashMap<String, Drawable> mHardCache = new LinkedHashMap<String, Drawable>(
-
MAX_CAPACITY / 2, 0.75f, true) {
-
private static final long serialVersionUID = 1L;
-
-
protected boolean removeEldestEntry(Entry<String, Drawable> eldest) {
-
if (size() > MAX_CAPACITY) {
-
// 将较少用到的图片从一级缓存挪到二级缓存中
-
-
mSoftCache.put(eldest.getKey(), new SoftReference<Drawable>(
-
eldest.getValue()));
-
return true;
-
}
-
return false;
-
};
-
};
-
-
public void CacheImageClear() {
-
mHardCache.clear();
-
mSoftCache.clear();
-
}
-
-
public Drawable getDrawableFromCache(String url) {
-
Drawable drawable = null;
-
synchronized (mHardCache) {
-
drawable = mHardCache.get(url);
-
if (drawable != null) {
-
// 类似LRU,将最近使用的图片放到最前面
-
-
mHardCache.remove(url);
-
mHardCache.put(url, drawable);
-
return drawable;
-
}
-
}
-
// 一级级缓存中没有找到,在二级缓存中查找
-
-
SoftReference<Drawable> softReference = mSoftCache.get(url);
-
if (softReference != null) {
-
drawable = softReference.get();
-
if (drawable == null) {
-
mSoftCache.remove(url);
-
}
-
-
}
-
return drawable;
-
}
-
-
public Drawable loadDrawable(final String imageUrl,
-
final ImageCallback imageCallback) {
-
-
Drawable drawable = getDrawableFromCache(imageUrl);
-
if (null != drawable) {
-
return drawable;
-
} else {
-
final Handler handler = new Handler() {
-
public void handleMessage(Message message) {
-
if (null != imageUrl && null != message
-
&& null != imageCallback && null != message.obj) {
-
try {
-
// 图片异步加载完后,通知主线程更新
-
-
imageCallback.imageLoaded((Drawable) message.obj,
-
imageUrl);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
};
-
-
// 缓存中没有图片,开启线程异步加载图片
-
-
new Thread() {
-
@Override
-
public void run() {
-
if (null != imageUrl) {
-
Drawable drawable = Util.createImageDrawable(imageUrl);
-
if (null != drawable) {
-
addImage2Cache(imageUrl, drawable);
-
Message message = handler
-
.obtainMessage(0, drawable);
-
handler.sendMessage(message);
-
}
-
}
-
}
-
}.start();
-
-
}
-
-
return null;
-
}
-
-
public void addImage2Cache(String url, Drawable value) {
-
if (value == null || url == null) {
-
return;
-
}
-
synchronized (mHardCache) {
-
mHardCache.put(url, value);
-
}
-
}
-
-
public interface ImageCallback {
-
public void imageLoaded(Drawable imageDrawable, String imageUrl);
-
}
-
}
如何使用呢?在getView方法里直接就可以调用了
-
Drawable cachedImage = cacheImageLoader.loadDrawable(path,
-
new CacheImageLoader.ImageCallback() {
-
-
@Override
-
public void imageLoaded(Drawable imageDrawable,
-
String imageUrl) {
-
if (imageDrawable != null) {
-
holder.imageView
-
.setBackgroundDrawable(imageDrawable);
-
}
-
}
-
-
});
-
if (cachedImage == null) {
-
holder.imageView
-
.setBackgroundResource(R.drawable.singer);
-
} else {
-
holder.imageView.setBackgroundDrawable(cachedImage);
-
}
这个工具类基本上就可以满足一般的需求了。想要进一步改进可以加入线程池或者在ListView中加入OnScrollListener,仅在停止滑动的时候加载图片等。
阅读(3649) | 评论(0) | 转发(0) |