①使用线程池管理加载图片的多个线程
②使用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);
}