ListView异步加载图片

这次做项目遇到了ListView中套GridView的情况,以前使用图片加载没有使用过缓存机制(这是不对的),基本上都是直接从服务器端加载图片。这次主要解决了两个问题,第一,listView滑动时图片不断进行闪烁重复;第二,图片的缓存问题。

异步加载图像的类(不记得是看的是哪位大神):

package com.hnust.cn.util;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.drawable.Drawable;
import android.os.Handler;

/***
 * 异步加载图像,引入内存缓存机制
 *
 */
public class AsyncImageLoader {
	//为了加快速度,在内存中开启缓存(主要用于图片较多,或者一张图片被多次访问)
	public Map<String, SoftReference<Drawable>> imageCache =new HashMap<String, SoftReference<Drawable>>();
	//创建线程池 一次最多只能执行5个线程
	private ExecutorService executorService=Executors.newFixedThreadPool(5);
	private final Handler handler=new Handler();
	/***
	 * 
	 * @param url
	 * @param callBack
	 * @return  返回内存中的缓存的图像,第一次加载返回null
	 */
	public Drawable loadDrawable(String url,final ImageCallback callBack){
		final String imageUrl=ConstansUtil.SERVER_PATH+"/upload/"+url;
		if(imageCache.containsKey(url)){
			SoftReference<Drawable> softReference=imageCache.get(imageUrl);
			if(softReference.get()!=null){
				return softReference.get();
			}
		}
		executorService.submit(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					final Drawable drawable=Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");
					imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
					handler.post(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							callBack.imageLoaded(drawable);
						}
					});
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		return null;
	}
	//对外界暴露出来的接口
	public interface ImageCallback{
		public void imageLoaded(Drawable imageDrawable);
	}
}

ListView滑动时图片总是出现闪烁,直到显示正确的图片,具体的错误原因:http://android.662p.com/forum.php?mod=viewthread&tid=6006

final List<Object> userList=(List<Object>) items.get(arg0).get(8);
		//add tag for image,to compare it when image load finish
		viewHolder.iv_user_photo.setTag(userList.get(0).toString());
		viewHolder.tv_userName.setText(userList.get(1).toString());
		viewHolder.tv_user_text.setText(items.get(arg0).get(1).toString());
		viewHolder.tv_location.setText(items.get(arg0).get(2).toString());
		viewHolder.tv_time.setText(items.get(arg0).get(5).toString());
		List<Object> iconList=(List<Object>) items.get(arg0).get(7);
		if(iconList==null){
			viewHolder.mImgGridView.setVisibility(View.INVISIBLE);
		}else{
			viewHolder.mImgGridView.setVisibility(View.VISIBLE);
			viewHolder.mImgGridView.setAdapter(new GridViewAdapter(context, arg0,iconList));
		}
		viewHolder.tv_good.setVisibility(View.VISIBLE);
		viewHolder.mListView.setAdapter(new CommentListViewAdapter(context));
		final TitlePopup popUp=new TitlePopup(context,Util.dip2px(context, 165), Util.dip2px(context, 40));
		popUp.addAction(new ActionItem(context, "赞", R.drawable.circle_praise));
		popUp.addAction(new ActionItem(context, "评论", R.drawable.circle_comment));
		popUp.setItemOnClickListener(this);
		viewHolder.btn_like_comment.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				popUp.setAnimationStyle(R.style.cricleBottomAnimation);
				popUp.show(v);
			}
		});
		AsyncImageLoader imageLoader=new AsyncImageLoader();
		Drawable cacheImage=imageLoader.loadDrawable(userList.get(0).toString(), new ImageCallback() {
			
			@Override
			public void imageLoaded(Drawable imageDrawable) {
				// 进行判断,如果tag与当前位置的URL一致那么就进行加载图片,如果不一致,那么不做任何处理
				if(viewHolder.iv_user_photo.getTag().equals(userList.get(0).toString())){			
					viewHolder.iv_user_photo.setImageDrawable(imageDrawable);
				}
			}
		});
		if(cacheImage!=null){
			viewHolder.iv_user_photo.setImageDrawable(cacheImage);
		}else{
			viewHolder.iv_user_photo.setImageResource(R.drawable.head_default);
		}
		return convertView;
在此只是做一个记录,以待下次进行查看.

你可能感兴趣的:(ListView异步加载图片)