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