• Android中图片的异步加载


    转:

    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);
            }
        }
    }
  • 相关阅读:
    Django orm self 自关联表
    postgresql数据库导入导出
    celery在项目中的使用
    P3405 [USACO16DEC]Cities and States S 【map使用】
    P1030 求先序排列 【已知中序后序求先序】
    P1305 新二叉树 【寻找根节点进行先序遍历】
    P1229 遍历问题 【已知先序后序求中序种类】
    P1364 医院设置 【带权值的树的重心】
    P3884 [JLOI2009]二叉树问题 【离线tarjan或数的向上遍历】
    P1827 [USACO3.4]美国血统 American Heritage【树的遍历】
  • 原文地址:https://www.cnblogs.com/vip-ygh/p/3955953.html
Copyright © 2020-2023  润新知