ListView异步批量加载图片
单线程轮循机制批量下载图片
例如:imageloader框架底层也是这么实现的!
思路:主线程向任务集合添加一个任务,工作线程从任务集合移除第一个任务,如果有任务一直移除,一直轮循,拿到图片之后解析成Bitmap,呈现的imageView当中。
package com.tarena.musicclient.adapter;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import com.tarena.musicclient.activity.R;
import com.tarena.musicclient.entity.Music;
import com.tarena.musicclient.util.BitmapUtils;
import com.tarena.musicclient.util.GlobalConsts;
import com.tarena.musicclient.util.HttpUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MusicAdapter extends BaseAdapter{
private Context context;
private List<Music> musics;
private LayoutInflater inflater;
//(2)声明任务集合
private List<ImageLoadTask> tasks=new ArrayList<ImageLoadTask>();
private ListView listView;
//声明用于轮循任务集合的工作线程
private Thread workThread;
//声明变量控制while循环
private boolean isLoop=true;
//声明缓存集合
private HashMap<String, SoftReference<Bitmap>> cache
=new HashMap<String, SoftReference<Bitmap>>();
//声明Handler 更新ImageView
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case HANDLER_LOAD_IMAGE_SUCCESS:
//给ImageView设置Bitmap
ImageLoadTask task=(ImageLoadTask)msg.obj;
//通过tag寻找到相应的ImageView
ImageView ivAlum=(ImageView)listView.findViewWithTag(task.position);
if(ivAlum!=null){
if(task.bitmap!=null){
ivAlum.setImageBitmap(task.bitmap);
}else{
ivAlum.setImageResource(R.drawable.ic_launcher);
}
}
break;
}
}
};
public static final int HANDLER_LOAD_IMAGE_SUCCESS=0;
public MusicAdapter(Context context, List<Music> musics, ListView listView) {
this.context=context;
this.musics=musics;
this.listView=listView;
inflater=LayoutInflater.from(context);
//(5)MusicAdapter有几个,工作线程就有几个
//对workThread进行初始化
workThread=new Thread(){
public void run() {
//(6)不断轮循任务集合
while(isLoop){
//如果任务集合不是空集
if(!tasks.isEmpty()){
//获取任务对象并且发送请求
ImageLoadTask task = tasks.remove(0);
//通过路径返回Bitmap对象
Bitmap bitmap=loadBitmap(task.path);
task.bitmap=bitmap;
//给相应的ImageView设置Bitmap handler
Message msg=new Message();
msg.what=HANDLER_LOAD_IMAGE_SUCCESS;
msg.obj=task;
handler.sendMessage(msg);
}else{
//同步代码块:一但调用了某个对象的wait()/notify()方法后,外面一定套一个以这个对象为锁的同步代码块
synchronized (workThread) {
//如果任务集合是空集 wait等待
try {
workThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
};
workThread.start();
}
/**
* 通过path 获取Bitmap
* @param path
* @return
*/
public Bitmap loadBitmap(String path){
Bitmap bitmap=null;
String uri=GlobalConsts.BASEURL+path;
try {
//实体转成字节数组,字节数组转成图片
HttpEntity entity=HttpUtils.send(HttpUtils.METHOD_GET, uri, null);
byte[] bytes=EntityUtils.toByteArray(entity);
bitmap=BitmapUtils.loadBitmap(bytes, 50, 50);
//向缓存集合中存储缓存图片
cache.put(path, new SoftReference<Bitmap>(bitmap));
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
public int getCount() {
return musics.size();
}
public Object getItem(int position) {
return musics.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(int