参考自http://blog.csdn.net/wanglong0537/article/details/6334005#

http://www.cnblogs.com/slider/archive/2011/11/22/2258942.html

http://www.iteye.com/topic/685986

ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法,先贴上异步加载图片主方法的代码:

package cn.wangmeng.test;import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;public class AsyncImageLoader {private HashMap<String, SoftReference<Drawable>> imageCache;public AsyncImageLoader() {imageCache = new HashMap<String, SoftReference<Drawable>>();}public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {if (imageCache.containsKey(imageUrl)) {SoftReference<Drawable> softReference = imageCache.get(imageUrl);Drawable drawable = softReference.get();if (drawable != null) {return drawable;}}final Handler handler = new Handler() {public void handleMessage(Message message) {imageCallback.imageLoaded((Drawable) message.obj, imageUrl);}};new Thread() {@Overridepublic void run() {Drawable drawable = loadImageFromUrl(imageUrl);imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));//把获得的drawable存入缓存Message message = handler.obtainMessage(0, drawable);//obtainmessage()与new message类似//obtainmessage()是从消息池拿来的一个msg,不必另开空间newhandler.sendMessage(message);}}.start();return null;}//从图片url获取图片drawable对象public static Drawable loadImageFromUrl(String url) {URL m;InputStream i = null;try {m = new URL(url);i = (InputStream) m.getContent();} catch (MalformedURLException e1) {e1.printStackTrace();} catch (IOException e) {e.printStackTrace();}Drawable d = Drawable.createFromStream(i, "src");return d;}public interface ImageCallback {public void imageLoaded(Drawable imageDrawable, String imageUrl);}}

注意这里使用了 SoftReference来缓存图片,允许 GC在需要的时候可以对缓存中的图片进行清理。

异步加载图片类AsyncImageLoader的实现方式

1,在自定义的adapter中调用 loadDrawable(ImageUrl, imageCallback),传入图片的网络地址和一个实现ImageCallback行为的对象(一个匿名实现的 ImageCallback接口的对象)

2,如果图片(通过imageUrl这个key值来判断)在缓存imageCache中不存在的话,图片将从单一(异步)的线程中下载并在下载结束时Drawable返回为null并通过 ImageCallback回调在 ImageAndTextListAdapter类中实现的 imageLoaded方法

3,如果图片确实存在于缓存中,就会马上返回drawable给adapter类的cachedImage,不会回调 ImageCallback

注:HashMap<String, SoftReference<Drawable>>(); 和平常常用的HashMap<key,value>是一样的

注:关于软引用:在Java中内存管理,引用分为四大类,强引用HardReference、弱引用WeakReference、软引用SoftReference和虚引用PhantomReference。它们的区别也很明显,HardReference对象是即使虚拟机内存吃紧抛出OOM也不会导致这一引用的对象被回收,而WeakReference等更适合于一些数量不多,但体积稍微庞大的对象,在这四个引用中,它是最容易被垃圾回收的,而我们对于显示类似Android Market中每个应用的App Icon时可以考虑使用SoftReference来解决内存不至于快速回收,同时当内存短缺面临Java VM崩溃抛出OOM前时,软引用将会强制回收内存,最后的虚引用一般没有实际意义,仅仅观察GC的活动状态,对于测试比较实用同时必须和ReferenceQueue一起使用。对于一组数据,我们可以通过HashMap的方式来添加一组SoftReference对象来临时保留一些数据,同时对于需要反复通过网络获取的不经常改变的内容,可以通过本地的文件系统或数据库来存储缓存。

几个辅助类文件:

图片和文字的实体类

package cn.wangmeng.test;public class ImageAndText {private String imageUrl;private String text;public ImageAndText(String imageUrl, String text) {this.imageUrl = imageUrl;this.text = text;}public String getImageUrl() {return imageUrl;}public String getText() {return text;}
}

view的缓存类

package cn.wangmeng.test;import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;public class ViewCache {private View baseView;private TextView textView;private ImageView imageView;public ViewCache(View baseView) {this.baseView = baseView;}public TextView getTextView() {if (textView == null) {textView = (TextView) baseView.findViewById(R.id.text);}return textView;}public ImageView getImageView() {if (imageView == null) {imageView = (ImageView) baseView.findViewById(R.id.image);}return imageView;}}

自定义adapter类

package cn.wangmeng.test;import java.util.List;import cn.wangmeng.test.AsyncImageLoader.ImageCallback;import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {private ListView listView;private AsyncImageLoader asyncImageLoader;public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {super(activity, 0, imageAndTexts);this.listView = listView;asyncImageLoader = new AsyncImageLoader();}public View getView(int position, View convertView, ViewGroup parent) {Activity activity = (Activity) getContext();// Inflate the views from XMLView rowView = convertView;ViewCache viewCache;if (rowView == null) {LayoutInflater inflater = activity.getLayoutInflater();rowView = inflater.inflate(R.layout.image_and_text_row, null);viewCache = new ViewCache(rowView);rowView.setTag(viewCache);} else {viewCache = (ViewCache) rowView.getTag();}ImageAndText imageAndText = getItem(position);// Load the image and set it on the ImageViewString imageUrl = imageAndText.getImageUrl();ImageView imageView = viewCache.getImageView();imageView.setTag(imageUrl);Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {public void imageLoaded(Drawable imageDrawable, String imageUrl) {ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);if (imageViewByTag != null) {imageViewByTag.setImageDrawable(imageDrawable);}}});if (cachedImage == null) {imageView.setImageResource(R.drawable.default_image);}else{imageView.setImageDrawable(cachedImage);}// Set the text on the TextViewTextView textView = viewCache.getTextView();textView.setText(imageAndText.getText());return rowView;}}

adapter类的一些实现方式

1,imageView.setTag(imageUrl);标记此imageUrl的imageView 待没有此图片回调imageLoaded时 取得对应此imageUrl的ImageView(imageViewByTag)

这样是为了保证在回调函数时,listview去更新自己对应item
2,没有此图片时,异步加载类中的loadDrawable返回null 回调imageLoaded放入图片

3,有此图片时,通过loadDrawable取得drawable给cachedImage,放入图片

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><ImageView android:id="@+id/image"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextView android:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>

主activity

package cn.wangmeng.test;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;public class AsyncListImage extends Activity {private ListView list;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);list=(ListView)findViewById(R.id.list);List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
//        ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");
//        ImageAndText test1=new ImageAndText("http://www.wangmeng.cn/images/ad/t1.gif", "test1");
//        ImageAndText test2=new ImageAndText("http://www.wangmeng.cn/images/ad/t3.gif", "test2");ImageAndText test=new ImageAndText("http://img3.douban.com/lpic/s11082606.jpg", "test");ImageAndText test1=new ImageAndText("http://img3.douban.com/lpic/s11181635.jpg", "test1");ImageAndText test2=new ImageAndText("http://img5.douban.com/lpic/s11169899.jpg", "test2");ImageAndText test3=new ImageAndText("http://img3.douban.com/lpic/s11192408.jpg", "test");ImageAndText test4=new ImageAndText("http://img1.douban.com/lpic/s11192434.jpg", "test");ImageAndText test5=new ImageAndText("http://img5.douban.com/lpic/s10324209.jpg", "test");ImageAndText test6=new ImageAndText("http://img5.douban.com/lpic/s11181029.jpg", "test");ImageAndText test7=new ImageAndText("http://img3.douban.com/lpic/s11218427.jpg", "test");ImageAndText test8=new ImageAndText("http://img3.douban.com/lpic/s11162616.jpg", "test");ImageAndText test9=new ImageAndText("http://img3.douban.com/lpic/s11082606.jpg", "test");dataArray.add(test);dataArray.add(test1);dataArray.add(test2);dataArray.add(test3);dataArray.add(test4);dataArray.add(test5);dataArray.add(test6);dataArray.add(test7);dataArray.add(test8);dataArray.add(test9);ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);list.setAdapter(adapter);}
}

自己动手实验吧 没问题 截图也看不出效果 主要总结下异步加载类到底如何运行的

补充:

关于代码中adapter类中的 super(activity, 0, imageAndTexts);

先来看官网的构造方法

Public Constructors
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int textViewResourceId)</nobr>

Constructor
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int,%20int)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int resource, int textViewResourceId)</nobr>

Constructor
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int,%20T%5B%5D)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int textViewResourceId, T[] objects)</nobr>

Constructor
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int,%20int,%20T%5B%5D)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int resource, int textViewResourceId, T[] objects)</nobr>

Constructor
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int,%20java.util.List&lt;T&gt;)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int textViewResourceId, <a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/java/util/List.html"> List</a>&lt;T&gt; objects)</nobr>

Constructor
<nobr></nobr> <nobr><span class="sympad"><a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context,%20int,%20int,%20java.util.List&lt;T&gt;)">ArrayAdapter</a></span>(<a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/android/content/Context.html">Context</a> context, int resource, int textViewResourceId, <a href="file:///D:/android-sdk-windows/android-sdk-windows/docs/reference/java/util/List.html"> List</a>&lt;T&gt; objects)</nobr>

Constructor

选取 ArrayAdapter( Context context, int textViewResourceId, List<T> objects) 是为了把list传来直接给ArrayAdapter填充了数据 textViewResourceId设为0(即省略此参数)

Android实现ListView异步加载图片总结相关推荐

  1. Android实现ListView异步加载图片

    转: http://www.iteye.com/topic/685986 ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法 ...

  2. Android之ListView异步加载图片且仅显示可见子项中的图片

    折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整 ...

  3. android开发小技巧:实现listview异步加载图片

    2019独角兽企业重金招聘Python工程师标准>>> 针对listview异步加载图片这个问题,麦子学院android开发老师讲了一种非常实用的方法,麦子学院android开发老师 ...

  4. Android ListView异步加载图片乱序问题,原因分析及解决方案

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android所有系统自带的控件当中,ListView这个控件算是 ...

  5. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  6. Android ListView 异步加载图片

    使用ListView.GridView来展示图片是项目中经常遇到的情况,这里使用官方文档的BitmapFun稍作修改实现ListView 异步加载图片效果. 实现原理:给ListView 注册一个 滚 ...

  7. Android开发之ListView异步加载图片

    ListView这个控件对于大家肯定不会陌生,即使你是初学者相信也会用ListView.因为ListView这个控件实在是太常用,可以说基本上每一个项目开发都会用到它,今天这篇博客主要讲解,ListV ...

  8. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  9. ListView异步加载图片,完美实现图文混排

    昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...

最新文章

  1. 异构GoldenGate 12c 双向复制配置
  2. C#3.0 自动属性——只能在简单属性上偷懒
  3. Linux下部署Tomcat项目笔记
  4. 22届腾讯暑期实习三轮面试面经(已oc)
  5. php数组的下标、extract函数
  6. javascript正则表达式入门
  7. php获取推特feed twitter timeline feed
  8. visio中给文字添加上下标
  9. Servlet体系及方法
  10. 云计算的下一个时代——“容器时代”
  11. java retainall_Java Set retainAll()用法及代码示例
  12. distpicker.js 三级联动,修改地址时设置默认值
  13. 【巴马火麻茶】调节三高、治疗失眠、排毒减肥,轻松get长寿的秘密!
  14. js创建节点删除节点实例
  15. 关于日期插件在chrome中出现被遮挡的问题
  16. android常用api大全,Android开发个人总结常用的api
  17. A Tutorial on Learned Multi-dimensional Indexes
  18. 短信字数的验证JAVA代码
  19. 上半年亏损6700万美元,连亏三年的Mobileye正式提交IPO申请
  20. 下载mrt需要java_MRT(MODIS Reprojection Tool)下载及安装方法

热门文章

  1. 创建 OVS vlan100 netwrok - 每天5分钟玩转 OpenStack(137)
  2. 【第一篇】Volley的使用之json请求
  3. java读取各类型的文件
  4. web前端开发 —— 一个对联效果
  5. 是什么让你的ExtJS应用程序运行缓慢?
  6. 真不好意思,让你贱笑了
  7. 下班前网上搜集的方法哈哈
  8. Oracle外键级联删除和级联更新
  9. ASP.NET Core开发Docker部署
  10. 2、Angular2 Directive