单线程轮循机制批量下载图片

listview 在为item 添加从网上下载下来的图片时, 如果每次都整合一个item时都需要new一个Thread去下载图片,listview长时间滑动时会产生大量线程。

用单线程轮循机制则可以解决这个问题

步骤如下:

1、需要一个任务集合

class imageViewTask{
		String path;
		Bitmap bitmap;
		int position;
	}
// 任务集合
	private List<imageViewTask> imageviews = new ArrayList<MusicAdapter.imageViewTask>();

2、在构造方法中创建一个线程,通过任务集合中的path去网上下载图片获得bitmap并放置在这个任务中以Message的obj形式传送给handler处理。

只有在为listview设置适配器时才需要创建这个工作线程, 且只有一个


(while(true)循环 在activity  调用OnDestroy )才会终止

// 获得图片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();
							}
						}
					}
					
				}
//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工具

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中放入图片时的方便。

// 给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

// 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;

			}
		};
	};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值