Android中图片的异步加载

转:缓存

一、  为何要异步加载图片网络

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

二、  SoftReference的做用ide

栈内存—引用spa

堆内存—对象线程

Eg:code

Object obj = new Object();对象

Obj = null;blog

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

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

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

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

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

在这里咱们使用SoftReference对象来创建图片缓存

三、  异步加载图片的方法

基本流程:

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);
        }
    }
}
相关文章
相关标签/搜索