转:

1、  为什么要异步加载图片

下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验

2、  SoftReference的作用

栈内存—引用

堆内存—对象

Eg:

Object obj = new Object();

Obj = null;

当垃圾收集器启动时,会回收对象;

当一个对象没有任何引用指向,就会被回收。

SoftReference<Object>sr = new SoftReference<Object>(new Obnject());

引用是软引用,当垃圾回收器启动时,系统会判断内存是否充足,内存不足时,即使对象有引用指向,也会被回收。

Object obj = sr.get();获取软引用指向的对象,当已被回收时,返回NULL。

在这里我们使用SoftReference对象来建立图片缓存

3、  异步加载图片的方法

基本流程:

A、 获取图片URL

B、 根据URL查询缓存

Eg:假如取回了20条微博,其中5条微博是同一个人发的,这样这个人的头像就要被取回5次,这是不合理的。

解决方法:把从网络上下载的图片以键值对的方式放到缓存里,键是URL,值是下载的图片,下次再去读取图片时,先看URL是否在缓存里,如果在,就不用下载了。

C、 访问缓存or访问网络

D、 得到图片对象

E、  显示图片

代码示例:

/**
 * 实现图片的异步加载
 * @author Zhu
 *
 */
public class AsyncImageLoader {
    //图片缓存对象,键是URL,值是SoftReference对象,该对象指向一个Drawable对象
    private Map<String,SoftReference<Drawable>> imageCache =
        new HashMap<String,SoftReference<Drawable>>();
    /**
     * 实现图片的异步加载
     * @param imageUrl
     * @return
     */
    public Drawable loadDrawable(final String imageUrl){
        //查询缓存,查看当前要下载的图片是否已经在缓存中
        if(imageCache.containsKey(imageUrl)){
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            if(softReference.get()!=null){
                return softReference.get();//还没被回收
            }
        }
        final Handler handler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                //Handler是与主程序处于同一线程的,在这里可以写加载完图片的处理,显示or存储or...
            }

        };
        //新开辟一个线程
        new Thread(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                super.run();
                Drawable drawable = loadImageFromUrl(imageUrl);
                imageCache.put(imageUrl,new SoftReference<Drawable>(drawable));
                Message message = handler.obtainMessage(0,drawable);
                handler.sendMessage(message);
            }

        }.start();
        return null;
    }
    /**
     * 根据图片的URL从网络上下载图片
     * @param imageUrl
     * @return
     */
    public Drawable loadImageFromUrl(String imageUrl){
        try{
            //根据图片的URL,下载图片,并生成一个Drawable对象
            return Drawable.createFromStream(new URL(imageUrl).openStream(), "src");
                       //另一种下载图片的方法:
                     //  Drawable icon;
                    //  HttpURLConnection hc=(HttpURLConnection)new URL(imageUrl).openConnection();
             //    icon=new Drawable(hc.getInputStream());
             //    hc.disconnect();
        }catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    }
}

 

posted on 2014-09-04 14:00  Y.G.H  阅读(185)  评论(0编辑  收藏  举报