使用线程池和LruCache异步加载图片(防止错位)


①使用线程池管理加载图片的多个线程

②使用LruCache缓存图片,避免重复加载

③给ImageView设置Tag,可有效防止异步加载时产生的错位现象


一、BitmapCache.java,LruCache的封装类

public class BitmapCache {
	private LruCache<String, Bitmap> mCache;

	public BitmapCache(final Vector<String> loadTask) {
//		int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024);
//		int maxSize = maxMemory / 8;
		//申请24M空间
		int maxSize = 24 * 1024 * 1024;
		mCache = new LruCache<String, Bitmap>(maxSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
//				return bitmap.getByteCount()/1024;
				return bitmap.getRowBytes() * bitmap.getHeight();
			}

			@Override
			protected void entryRemoved(boolean evicted, String key,
					Bitmap oldValue, Bitmap newValue) {
				super.entryRemoved(evicted, key, oldValue, newValue);
				//回收时移除loadTask对应的项
				loadTask.remove(key);
			}
		};
	}

	public Bitmap getBitmap(String url) {
		return mCache.get(url);
	}

	public void putBitmap(String url, Bitmap bitmap) {
		mCache.put(url, bitmap);
	}
}


二、异步加载图片代码

// 加载后的任务列表
	public final static Vector<String> loadTask;
	// 存放缩放的图片的缓存
	private static BitmapCache bitmapCache;
	static {
		loadTask = new Vector<String>();
		// 一级内存缓存基于 LruCache
		bitmapCache = new BitmapCache(loadTask);
	}
	// 最大线程数
	private static final int MAX_THREAD_NUM = 20;
	// 线程池
	private static ExecutorService threadPools = Executors
			.newFixedThreadPool(MAX_THREAD_NUM);

	public Bitmap loadmg(final ImageView imageView,
			final ImageCallback callback) {
		final String path = (String) imageView.getTag();

		if (bitmapCache.getBitmap(path) != null) {
			return bitmapCache.getBitmap(path);
		}

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				callback.imageLoadedNotify(imageView, (Bitmap) msg.obj);
			}
		};

		if (loadTask.contains(path)) {
			return null;
		}
		loadTask.add(path);

		Thread thread = new Thread() {
			@Override
			public void run() {
				 Bitmap bitmap = getBitmap(path); //这里应该是异步加载的方法
				if (bitmap != null) {
					if (Utils.check3DVideoBoolean(path)) {
						bitmap = Bitmap.createBitmap(bitmap, 0, 0,
								bitmap.getWidth() / 2, bitmap.getHeight());
					}
					bitmapCache.putBitmap(path, bitmap);
					Message msg = new Message();
					msg.obj = bitmap;
					handler.sendMessage(msg);
				}
			}
		};
		threadPools.execute(thread);
		return null;
	}


三、加载完成后的回调接口ImageCallback

public interface ImageCallback {
		public void imageLoadedNotify(ImageView imageView, Bitmap imgBitmap);
	}

四、adapter中的ImageView设置图片

final VideoInfo videoinfo = arr.get(0);
				if (videoinfo.getFilePath() != null
						&& !videoinfo.getFilePath().trim().isEmpty()) {
					holder.movieImage.setTag(videoinfo.getFilePath());
					Bitmap bitmap = new VideoUtils().loadImg(
							holder.movieImage, new ImageCallback() {
								@Override
								public void imageLoadedNotify(ImageView imageView,
										Bitmap imgBitmap) {
									//防止图片错位
									if (imageView.getTag().equals(videoinfo.getFilePath())) {
										imageView.setImageBitmap(imgBitmap);
									}
								}
							});
					if (bitmap != null) {
						//设置从缓存获取的图片
						if (!bitmap.isRecycled()) {
							holder.movieImage.setImageBitmap(bitmap);
						}
					} else {
						//设置缺省图片
						holder.movieImage
								.setImageResource(R.drawable.local_vid_shipin_picture_border);
					}
				} else {
					//设置缺省图片
					holder.movieImage
							.setImageResource(R.drawable.local_vid_shipin_picture_border);
				}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值