ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很好滚动流畅是做不到的
所以这里就需要把这些信息利用多线程实现异步加载
实现这样功能的类:
public class AsyncImageLoader {
private HashMap<String, SoftReference<Drawable>> imageCache;
public AsyncImageLoader() {
this.imageCache = new HashMap<String, SoftReference<Drawable>>();
}
// 下载图片
public static Drawable loadImageFromUrl(String url) {
InputStream localInputStream = null;
try {
localInputStream = (InputStream) new URL(url).getContent();
Drawable localDrawable = null;
if (localInputStream != null)
localDrawable = Drawable.createFromStream(localInputStream,
"src");
return localDrawable;
} catch (Exception localException) {
localException.printStackTrace();
return null;
}
}
public HashMap<String, SoftReference<Drawable>> getImageCache() {
return imageCache;
}
public void setImageCache(
HashMap<String, SoftReference<Drawable>> imageCache) {
this.imageCache = imageCache;
}
@SuppressWarnings("unchecked")
public Drawable loadDrawable(String imageURL,
ImageCallback paramImageCallback) {
boolean bool = this.imageCache.containsKey(imageURL);
Drawable localDrawable = null;
if (bool) {
localDrawable = (Drawable) ((SoftReference) (imageCache)
.get(imageURL)).get();
return localDrawable;
} else {
ImageHandler imageHandler = new ImageHandler(this,
paramImageCallback, imageURL);
new ImageThread(this, imageURL, imageHandler).start();
}
return localDrawable;
}
public abstract interface ImageCallback {
public abstract void imageLoaded(Drawable drawable, String imageUrl);
}
class ImageHandler extends Handler {
AsyncImageLoader asyncImageLoader;
ImageCallback imageCallback;
String imageUrl;
public ImageHandler(AsyncImageLoader asyncImageLoader,
ImageCallback paramImageCallback, String paramString) {
this.asyncImageLoader = asyncImageLoader;
this.imageCallback = paramImageCallback;
this.imageUrl = paramString;
}
public void handleMessage(Message paramMessage) {
if (this.imageCallback != null) {
Drawable localDrawable = (Drawable) paramMessage.obj;
// 将图片和图片的URL 传给回调函数,在回调函数中进行相应操作。
imageCallback.imageLoaded(localDrawable, this.imageUrl);
}
}
}
class ImageThread extends Thread {
private AsyncImageLoader asyncImageLoader;
private String imageURL;
private ImageHandler imageHandler;
public ImageThread(AsyncImageLoader asyncImageLoader, String imageURL,
ImageHandler imageHandler) {
this.asyncImageLoader = asyncImageLoader;
this.imageURL = imageURL;
this.imageHandler = imageHandler;
}
public void run() {
Drawable localDrawable = AsyncImageLoader
.loadImageFromUrl(this.imageURL);
// 将新下载的图片存入imageCache
HashMap imageCache = asyncImageLoader.getImageCache();
String str = this.imageURL;
SoftReference localSoftReference = new SoftReference(localDrawable);
imageCache.put(str, localSoftReference);
Message localMessage = this.imageHandler.obtainMessage(0,
localDrawable);
// 将图片 通过消息发送给hander
this.imageHandler.sendMessage(localMessage);
}
}
}
注意这里使用了 SoftReference来缓存图片,允许 GC在需要的时候可以对缓存中的图片进行清理。它这样工作:
<!--[if !supportLists]-->l <!--[endif]-->调用 loadDrawable(ImageUrl, imageCallback),传入一个匿名实现的 ImageCallback接口
<!--[if !supportLists]-->l <!--[endif]-->如果图片在缓存中不存在的话,图片将从单一的线程中下载并在下载结束时通过 ImageCallback回调
<!--[if !supportLists]-->l <!--[endif]-->如果图片确实存在于缓存中,就会马上返回,不会回调 ImageCallback