您的位置:首页 > 移动开发 > Android开发

Android 图片如何高效加载与缓存 (5) —— RecyclerView与自定义线程池结合 优化加载

2016-04-14 00:49 561 查看

假设

首先,让我们假设有一个存在 10000 张图片的列表。

用户进入列表之后,便迫不及待地要跑到最下面,看最下面的图片。这时候如果我们使用的是一个队列进行加载任务的话,那么用户就要等待前面的9900+张的图片加载完成之后才能看到想看到的图片了。

而这不是我们所希望的。我们希望的是用户滑动到哪里,就加载哪里的资源,而其他地方的东西就要回收掉,以节省空间。

1.修改RecyclerView的View回收方法

在RecyclerView.Adapter里面,我们只需要修改一下当View被移除的时候的方法,这一步很简单:

@Override
public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
//获取被移除的ViewHolder
ImageItemViewHolder viewHolder = (ImageItemViewHolder)holder;

//从ViewHolder里面获取唯一的TAG,然后交由自定义的线程池来终止任务
OCImageLoader.loader().cancelTask(viewHolder.imageView.getTag().toString() , false);
}


2.创建线程池终止任务的方法

/**
* 终止任务
* @param tag   任务唯一TAG
* @param isContainText TAG相似即终止
* @return  处理结果
*/
public boolean cancelTask(String tag , boolean isContainText){

//终止线程

synchronized (this){

//如果TAG相似,则进行终止所有相似的线程.比如 123_ATask  123_BTask 都拥有"123"这个字段,这就是相似
if (isContainText){
Log.d("OCThread cancelTask", "Request to cancel TAG: "+tag);

//用迭代器来遍历Task列表
Iterator<String> keysSet = runnableMap.keySet().iterator();
while ( keysSet.hasNext() ){
String key = keysSet.next();
Log.d("OCThread cancelTask", "KEY:"+key);

//如果TAG是相似的,则从列表中消除并终止
if ( key.contains(tag) ){
remove(runnableMap.get(key));
FutureTask task = runnableMap.remove(key);
if (task != null){
task.cancel(true);
}
Log.d("OCThread cancelTask", "Task Canceled TAG: "+tag);
return true;
}
}
Log.d("OCThread cancelTask", "TAG dose not exist. Skipped. ");
return false;
}else{
//精确TAG终止线程.TAG必须两者字符串完全一致才能终止

if ( runnableMap.containsKey(tag) ){
Log.d("OCThread cancelTask", "Task Canceled TAG: "+tag);
remove(runnableMap.get(tag));
FutureTask task = runnableMap.remove(tag);
if (task != null){
task.cancel(true);
}
return true;
}else{
Log.d("OCThread cancelTask", "TAG dose not exist. Skipped. ");
return false;
}
}
}

}


3.效果图

为了图片大小不超过上传限制 2MB …. 只能调成黑白的了…

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息