Android 实现单线程轮循机制批量下载图片
listview 在为item 添加从网上下载下来的图片时, 如果每次都整合一个item时都需要new一个Thread去下载图片,listview长时间滑动时会产生大量线程。
用单线程轮循机制则可以解决这个问题
步骤如下:
1、需要一个任务集合
代码语言:javascript复制class imageViewTask{
String path;
Bitmap bitmap;
int position;
}
代码语言:javascript复制// 任务集合
private List<imageViewTask imageviews = new ArrayList<MusicAdapter.imageViewTask ();
2、在构造方法中创建一个线程,通过任务集合中的path去网上下载图片获得bitmap并放置在这个任务中以Message的obj形式传送给handler处理。
只有在为listview设置适配器时才需要创建这个工作线程, 且只有一个
(while(true)循环 在activity 调用OnDestroy )才会终止
代码语言:javascript复制// 获得图片bitmap
workThread = new Thread(){
public void run() {
while(isLoop){
if(!imageviews.isEmpty()){
try {
Message msg = new Message();
// 获得图片的bitmap
msg.obj = GetImageviewBitmap();
msg.what = HANDLER_LOAD_IMAGEVIEW_SUCCESS;
// 发消息给主线程
handler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}else{
synchronized (workThread) {
try {
//任务队列为空则等待
workThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
代码语言:javascript复制//GetImageviewBitmap()方法
// 获得图片的bitmap
private imageViewTask GetImageviewBitmap() throws Exception, IOException {
imageViewTask ivt = imageviews.remove(0);
String uri = BasicUri.BasicHttpUri ivt.path;
HttpEntity entity = new HttpUtils().SetHttp(uri, HttpUtils.GET_METHOD, null);
byte[] bytes = EntityUtils.toByteArray(entity);
Bitmap bitmap = BitmapUtils.loadBitmap(bytes, 50, 50);
// 将网上下载的图片存入缓存集合中
map.put(ivt.path, new SoftReference<Bitmap (bitmap));
ivt.bitmap = bitmap;
return ivt;
}
};
workThread.start();
}
这个是httpUtils工具
代码语言:javascript复制public class HttpUtils {
public final static int GET_METHOD = 1;
public final static int POST_MEHTOD = 2;
/**
* 构造方法
* @param uri 路径
* @param method 发送消息模式 GET_METHOD用get方式传送消息 POST_MEHTOD用post方式传送消息
*/
public static HttpEntity SetHttp(String uri, int method, List<NameValuePair pairs) throws Exception{
HttpClient client=new DefaultHttpClient();
HttpResponse resp = null;
switch (GET_METHOD) {
// 用get方式发送消息
case GET_METHOD:
HttpGet get=new HttpGet(uri);
resp=client.execute(get);
break;
// 用post方式发送消息
case POST_MEHTOD:
HttpPost post=new HttpPost(uri);
HttpEntity entity=new UrlEncodedFormEntity( pairs, "utf-8");
post.setEntity(entity);
post.setHeader("Content-Type",
"application/x-www-form-urlencoded");
resp=client.execute(post);
break;
}
return resp.getEntity();
}
}
3、在自定义adapter 的setView方法中在任务中放置图片下载的path和position, 并为item中的imageview设置标记, 为了在listview的item中放入图片时的方便。
代码语言:javascript复制// 给imageview设置标记
holder.iv.setTag(position);
// 增加任务队列
imageViewTask task = new imageViewTask();
task.path = musics.get(position).getAlbumpic();
task.position = position;
imageviews.add(task);
// 通知工作线程可以下载图片了
synchronized (workThread) {
workThread.notify();
}
4、传送消息给主线程,让hanler去更新UI
代码语言:javascript复制// handler
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case HANDLER_LOAD_IMAGEVIEW_SUCCESS:
// 更新UI
imageViewTask ivt = (imageViewTask) msg.obj;
ImageView iv = (ImageView) listview.findViewWithTag(ivt.position);
if(iv != null){
if(ivt.bitmap != null)
iv.setImageBitmap(ivt.bitmap);
}else{
iv.setImageResource(R.drawable.ic_launcher);
}
break;
}
};
};
以上就是使用Android 批量下载图片的讲解,如有疑问请留言或者到本站社区进行交流讨论,大家共同进步,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!