package com.naxieshu.util;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
/**
* 异步加截图片类
* @author Hai Jiang
* @Email 672335219@qq.ciom
* @Data 2014-2-26
*/
public class AsyncImageTask {
//缓存图片 把图片的软引用放到map中
private Map<String, SoftReference<Drawable>> imageMap;
//构造器
public AsyncImageTask() {
super();
this.imageMap = new HashMap<String, SoftReference<Drawable>>();
}
//ID为标记,标记哪条记录image . 这个ID来自于自定义adapter的getView()方法中其中一个参数position
public Drawable loadImage(final int id, final String imageUrl,
final ImageCallback callback){
//先看缓存(Map)中是否存在
if(imageMap.containsKey(imageUrl)){
SoftReference<Drawable> softReference = imageMap.get(imageUrl);
Drawable drawable = softReference.get();
if(drawable != null){
return drawable;
}
}
//主线程更新图片
final Handler handler = new Handler() {
public void handleMessage(Message message) {
callback.imageLoaded((Drawable) message.obj, id);
}
};
//加载图片的线程
new Thread() {
public void run() {
//加载图片
Drawable drawable = AsyncImageTask.loadImageByUrl(imageUrl);
//加入缓存集合中 注意 这里就要把得到的图片变成软引用放到map中了
imageMap.put(imageUrl, new SoftReference<Drawable>(drawable));
//通知消息主线程更新UI . 这里就是是否能异步刷新的留意点.
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
//到这里就获取图片的静态方法就完了
}
//根据图片地址加载图片,并保存为Drawable
//这里不用说了吧.都是一些基本的.从API从可以看
public static Drawable loadImageByUrl(String imageUrl){
URL url = null;
InputStream inputStream = null;
try {
url = new URL(Constant.TARGETURL+imageUrl);
inputStream = (InputStream) url.getContent();
Drawable drawable = Drawable.createFromStream(inputStream,"src");
return drawable;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//利用接口回调,更新图片UI
public interface ImageCallback {
public void imageLoaded(Drawable obj, int id);
}
}package com.naxieshu.adapter;
import java.lang.ref.SoftReference;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
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.SimpleAdapter;
import android.widget.TextView;
import com.naxieshu.activity.FindActivity;
import com.naxieshu.activity.R;
import com.naxieshu.domain.Book;
import com.naxieshu.util.AsyncImageTask;
import com.naxieshu.util.AsyncImageTask.ImageCallback;
import com.naxieshu.util.ImageUtil;
/**
* 自定义List内容控件
* @author Hai Jiang
* @Email 672335219@qq.ciom
* @Data 2014-2-26
*/
public class MyListAdapter extends SimpleAdapter{
//要显示在LISTVIEW中的数据源
public List<? extends Map<String, ?>> data;
private LayoutInflater inflater;
private AsyncImageTask imageTask;
private ListView listView;
public MyListAdapter(ListView listView,Context context,
List<? extends Map<String, ?>> data) {
super(context, data, 0, null, null);
this.data = data;
this.listView = listView;
inflater = LayoutInflater.from(context);
imageTask = new AsyncImageTask();
}
/**
* 在创建View资源对象的时候提供效率的缓存策略
*/
class ViewHold{
//book.cover
public ImageView image;
//book.title book.shortIntro
public TextView namtView,idView,introView;
}
ViewHold hold =null;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//判断是否第一次执行convertView(显示屏),如果是第一次就进行布局资源的创建操作
if (convertView == null){
hold = new ViewHold();
//填充加载布局资源
convertView = inflater.inflate(R.layout.activity_find_listview, null);
hold.image = (ImageView)convertView.findViewById(R.id.bookImage);
hold.namtView = (TextView)convertView.findViewById(R.id.bookName);
hold.idView = (TextView)convertView.findViewById(R.id.bookId);
hold.introView = (TextView)convertView.findViewById(R.id.bookShortIntro);
//保存标记
convertView.setTag(hold);
} else {
hold = (ViewHold) convertView.getTag();
}
/**获取数据,进行数据填充*/
// 标记图片视图,注意不能放在上面
hold.image.setTag(position);
Book book = (Book) data.get(position).get(position+"");
//异步获取图片.注意: 这里就是上面说到的.我个人为了方便理解的: 它里面子线程获取图片时可能会有延迟.
// 主线程是不会等你这里的drawble得到值再继续往下走的.下面的判断是否获取网络图片就先给一个本地图它用着
Drawable drawable = imageTask.loadImage(position, book.getCover(),
new ImageCallback(){
//这里的position就是AsyncImageTask里面要用到的便到确定子线程通知主线程更新哪一行的ID.也就是下标
public void imageLoaded(Drawable image, int position) {
if (image != null) {
//获取刚才标识的组件,并更新
ImageView imageView = (ImageView) listView
.findViewWithTag(position);
if (imageView != null) {
imageView.setImageDrawable(image);
}
}
}
});
//判断是否获取网络图片.如果还没有取到.就用本地的
if (drawable != null) {
hold.image.setImageDrawable(drawable);
} else {
hold.image.setImageResource(R.drawable.ic_launcher);
}
hold.namtView.setText(book.getTitle());
hold.idView.setText(book.getId());
hold.idView.setVisibility(View.GONE);
hold.introView.setText(book.getShortIntro());
return convertView;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
}
安卓ListView自定义Adapter实时加载网络图片与缓存软引用图片之说明,布布扣,bubuko.com
安卓ListView自定义Adapter实时加载网络图片与缓存软引用图片之说明
原文:http://blog.csdn.net/java_jh/article/details/20068915