android 异步加载图片

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在需要的时候可以对缓存中的图片进行清理。它这样工作:

l        调用 loadDrawable(ImageUrl, imageCallback),传入一个匿名实现的 ImageCallback接口

l        如果图片在缓存中不存在的话,图片将从单一的线程中下载并在下载结束时通过 ImageCallback回调

l        如果图片确实存在于缓存中,就会马上返回,不会回调 ImageCallback


你可能感兴趣的:(android 异步加载图片)