ListView异步加载网络图片完美版之双缓存技术
问题描述:以前对ListView加载网络图片以及缓存机制进行了分析,本来自以为已经完美了,前段时间有朋友说还有问题,问题是AsyncTask中的线程池满了>128。以前控制线程数量的方法是在ListView处于Fling状态的时候不去启动下载线程,然而这样的做法没有从更本上控制线程的数量。
解决方案:今天我将通过生产者消费者模式+信号量来控制AsynTask的执行。
// 通过信号量控制同时执行的线程数
Semaphore mSemaphore = new Semaphore(50);
// 这里是任务的消费者,去任务队列取出下载任务,然后执行,当没有任务的时候消费者就等待
class Executor extends Thread {
@Override
public void run() {
while (true) {
ImageLoadTask task = null;
try {
task = mTasks.take();
if (task != null) {
mSemaphore.acquire();
task.execute();
task.cancel(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void loadImage(String url, BaseAdapter adapter, ViewHolder holder) {
resetPurgeTimer();
Bitmap bitmap = getBitmapFromCache(url);// 从缓存中读取
if (bitmap == null) {
holder.mImageView.setImageResource(R.drawable.ic_launcher);// 缓存没有设为默认图片
ImageLoadTask imageLoadTask = new ImageLoadTask(url, adapter);
try {
//将任务放入队列中
mTasks.put(imageLoadTask);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
holder.mImageView.setImageBitmap(bitmap);// 设为缓存图片
}
}
@Override
protected void onPostExecute(Bitmap result) {
mSemaphore.release();
if (result == null) {
return;
}
addImage2Cache(url, result);// 放入缓存
adapter.notifyDataSetChanged();// 触发getView方法执行,这个时候getView实际上会拿到刚刚缓存好的图片
}
总结:我本来还想了一种解决的办法就是,在ViewHold中保留一个AsynTask的引用,如果AsyncTask的状态为Running则将其cancle,但是没有cancle掉,希望知道的朋友解答一下。
分享到:
相关推荐
android listview 异步加载网络图片
ListView异步加载网络图片,SoftReference,有重复的Url直接返回资源
简洁 明确 listview异步加载图片
android listView图片异步加载(拖动时不加载,双缓存)
Android Listview异步加载图片,图片错位解决方案
Android实现ListView异步加载图片
ListView的异步加载图片并缓存,可以实现异步加载数据,异步加载图片,缓存图片,并且实现退出删除图片缓存
listview异步加载
listview异步加载图片,使用到了强引用
Android 异步加载图片,对ListView的异步加载图片的功能演示,主要根据url读取图片返回流的方法。为了方便演示,将请求图片的链接先固定,每读取好一个图片就更新,界面比较简单,当然你可以做成比较好的,像很多好...
android listview异步加载图片实例 用到了线程池 下载的图片会保存到本地 并在数据库中保留记录 再次加载时会直接从本地读取
listview 实现异步加载图片 三级缓存
实现了异步加载图片进度条,代码更具有规范性
Android中ListView全面完美的网络图片的异步加载,两种加载方式,利用了LruCache缓存,动态加载,只加载可见部分的图片.
ListView,异步加载,图片三级缓存。
listview 异步加载图片