ListView异步加载网络图片完美版之双缓存技术(续)

[align=center][b][size=x-large]ListView异步加载网络图片完美版之双缓存技术[/size][/b][/align]
[size=large][b]问题描述:[/b]以前对ListView加载网络图片以及缓存机制进行了分析,本来自以为已经完美了,前段时间有朋友说还有问题,问题是[color=red]AsyncTask中的线程池满了>128[/color]。以前控制线程数量的方法是在ListView处于Fling状态的时候不去启动下载线程,然而这样的做法没有从更本上控制线程的数量。
[b]解决方案:[/b]今天我将通过生产者消费者模式+信号量来控制AsynTask的执行。
[/size]

// 通过信号量控制同时执行的线程数
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实际上会拿到刚刚缓存好的图片
}


[size=large][b]总结:[/b]我本来还想了一种解决的办法就是,在ViewHold中保留一个AsynTask的引用,如果AsyncTask的状态为Running则将其cancle,但是没有cancle掉,希望知道的朋友解答一下。[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值