zoukankan      html  css  js  c++  java
  • viewpage listview gridview加载本地大图多图OOM处理办法

    很少上博客园写东西了.

    最近在写公司项目,由于需要加载本地相册通过viewpager方式来加载,

    最后发现直接进入界面就OOM了.

    经过几天的整理最终搞定.

    现在将加载本地和加载网络图片的缓存工具类贴出代码.

    需要用的直接调用其中的暴露出的方法,传入本地图片地址或网络图片地址 +imageview即可

    代码如有问题请及时跟帖或者加QQ30338970交流.

      1 package cn.haodehaode.utils;
      2 
      3 import android.graphics.Bitmap;
      4 import android.graphics.BitmapFactory;
      5 import android.os.AsyncTask;
      6 import android.support.v4.util.LruCache;
      7 import android.widget.ImageView;
      8 
      9 import java.net.HttpURLConnection;
     10 import java.net.URL;
     11 import java.util.HashSet;
     12 import java.util.Set;
     13 
     14 import cn.haodehaode.R;
     15 
     16 /**
     17  * 图片缓存
     18  * 异步加载网络图片
     19  *
     20  * @author JALEN  c9n9m@163.com
     21  * @version V1.0
     22  * @Title: ${FILE_NAME}
     23  * @Package cn.haodehaode.utils
     24  * @Description: ${todo}
     25  * @date 15/10/29 13:39
     26  */
     27 public class LruCacheImgUrlUtils {
     28 
     29     private static LruCache<String, Bitmap> mMemoryCache;
     30 
     31     private static LruCacheImgUrlUtils lruCacheSingleton;
     32 
     33 
     34     /**
     35      * 记录所有正在下载或等待下载的任务。
     36      */
     37     private static Set<BitmapWorkerTasks> taskCollection;
     38 
     39     public static synchronized LruCacheImgUrlUtils getLruUrlCacheSingleton() {
     40         if (lruCacheSingleton == null) {
     41             lruCacheSingleton = new LruCacheImgUrlUtils();
     42 
     43             taskCollection = new HashSet<BitmapWorkerTasks>();
     44             // LruCache通过构造函数传入缓存值,以KB为单位。
     45             int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
     46             // 使用最大可用内存值的1/8作为缓存的大小。
     47             int cacheSize = maxMemory / 8;
     48             mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
     49                 @Override
     50                 protected int sizeOf(String key, Bitmap bitmap) {
     51                     // 重写此方法来衡量每张图片的大小,默认返回图片数量。
     52                     return bitmap.getByteCount() / 1024;
     53                 }
     54             };
     55         }
     56         return lruCacheSingleton;
     57     }
     58 
     59 
     60     /**
     61      * 将一张图片存储到LruCache中。
     62      *
     63      * @param key    LruCache的键,这里传入图片的URL地址。
     64      * @param bitmap LruCache的键,这里传入从网络上下载的Bitmap对象。
     65      */
     66     public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
     67         if (getBitmapFromMemoryCache(key) == null) {
     68             mMemoryCache.put(key, bitmap);
     69         }
     70     }
     71 
     72     /**
     73      * 从LruCache中获取一张图片,如果不存在就返回null。
     74      *
     75      * @param key LruCache的键,这里传入图片的URL地址。
     76      * @return 对应传入键的Bitmap对象,或者null。
     77      */
     78     public Bitmap getBitmapFromMemoryCache(String key) {
     79         return mMemoryCache.get(key);
     80     }
     81 
     82 
     83     /**
     84      * 给ImageView设置图片。首先从LruCache中取出图片的缓存,设置到ImageView上。如果LruCache中没有该图片的缓存,
     85      * 就给ImageView设置一张默认图片。
     86      *
     87      * @param imageUrl  图片的URL地址,用于作为LruCache的键。
     88      * @param imageView 用于显示图片的控件。
     89      */
     90     public void setImageView(String imageUrl, ImageView imageView) {
     91         Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
     92         if (bitmap != null) {
     93             imageView.setImageBitmap(bitmap);
     94         } else {
     95             imageView.setImageResource(R.drawable.empty_photo);
     96             BitmapWorkerTasks task = new BitmapWorkerTasks(imageView);
     97             task.execute(imageUrl);
     98         }
     99     }
    100 
    101 
    102     /**
    103      * 异步下载图片的任务。
    104      *
    105      * @author guolin
    106      */
    107     class BitmapWorkerTasks extends AsyncTask<String, Void, Bitmap> {
    108 
    109         private ImageView mImageView;
    110 
    111         public BitmapWorkerTasks(ImageView imageView) {
    112             mImageView = imageView;
    113         }
    114 
    115         /**
    116          * 图片的URL地址
    117          */
    118         private String imageUrl;
    119 
    120         @Override
    121         protected Bitmap doInBackground(String... params) {
    122             imageUrl = params[0];
    123             // 在后台开始下载图片
    124             Bitmap bitmap = downloadBitmap(params[0]);
    125             if (bitmap != null) {
    126                 // 图片下载完成后缓存到LrcCache中
    127                 addBitmapToMemoryCache(params[0], bitmap);
    128             }
    129             return bitmap;
    130         }
    131 
    132         @Override
    133         protected void onPostExecute(Bitmap bitmap) {
    134             super.onPostExecute(bitmap);
    135             // 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。
    136             if (mImageView != null && bitmap != null) {
    137                 mImageView.setImageBitmap(bitmap);
    138             }
    139             taskCollection.remove(this);
    140         }
    141 
    142         /**
    143          * 建立HTTP请求,并获取Bitmap对象。
    144          *
    145          * @param imageUrl 图片的URL地址
    146          * @return 解析后的Bitmap对象
    147          */
    148         private Bitmap downloadBitmap(String imageUrl) {
    149             Bitmap bitmap = null;
    150             HttpURLConnection con = null;
    151             try {
    152                 URL url = new URL(imageUrl);
    153                 con = (HttpURLConnection) url.openConnection();
    154                 con.setConnectTimeout(5 * 1000);
    155                 con.setReadTimeout(10 * 1000);
    156                 bitmap = BitmapFactory.decodeStream(con.getInputStream());
    157             } catch (Exception e) {
    158                 e.printStackTrace();
    159             } finally {
    160                 if (con != null) {
    161                     con.disconnect();
    162                 }
    163             }
    164             return bitmap;
    165         }
    166 
    167     }
    168 
    169 
    170 }
    package cn.haodehaode.utils;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.AsyncTask;
    import android.support.v4.util.LruCache;
    import android.widget.ImageView;
    
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.HashSet;
    import java.util.Set;
    
    import cn.haodehaode.R;
    
    /**
     * 图片缓存
     *
     * @author JALEN  c9n9m@163.com
     * @version V1.0
     * @Title: ${FILE_NAME}
     * @Package cn.haodehaode.utils
     * @Description: ${todo}
     * @date 15/10/29 13:39
     */
    public class LruCacheImgUtils {
    
        private static LruCache<String, Bitmap> mMemoryCache;
    
        private static LruCacheImgUtils lruCacheSingleton;
    
    
        public static synchronized LruCacheImgUtils getLruCacheSingleton() {
            if (lruCacheSingleton == null) {
                lruCacheSingleton = new LruCacheImgUtils();
    
                // LruCache通过构造函数传入缓存值,以KB为单位。
                int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
                // 使用最大可用内存值的1/8作为缓存的大小。
                int cacheSize = maxMemory / 8;
                mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
                    @Override
                    protected int sizeOf(String key, Bitmap bitmap) {
                        // 重写此方法来衡量每张图片的大小,默认返回图片数量。
                        return bitmap.getByteCount() / 1024;
                    }
                };
            }
            return lruCacheSingleton;
        }
    
        public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
            if (getBitmapFromMemCache(key) == null) {
                mMemoryCache.put(key, bitmap);
            }
        }
    
        public Bitmap getBitmapFromMemCache(String key) {
            return mMemoryCache.get(key);
        }
    
    
        public void loadBitmap(String path, ImageView imageView) {
            final Bitmap bitmap = getBitmapFromMemCache(path);
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
            } else {
                imageView.setImageResource(R.drawable.default_image);
                BitmapWorkerTask task = new BitmapWorkerTask(imageView);
                task.execute(path);
            }
        }
    
    
        public Bitmap decodeSampledBitmapFromResource(String path,
                                                      int reqWidth, int reqHeight) {
            // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);
            // 调用上面定义的方法计算inSampleSize值
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            // 使用获取到的inSampleSize值再次解析图片
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFile(path, options);
        }
    
        public static int calculateInSampleSize(BitmapFactory.Options options,
                                                int reqWidth, int reqHeight) {
            // 源图片的高度和宽度
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
            if (height > reqHeight || width > reqWidth) {
                // 计算出实际宽高和目标宽高的比率
                final int heightRatio = Math.round((float) height / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);
                // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
                // 一定都会大于等于目标的宽和高。
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }
            return inSampleSize;
        }
    
    
        class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
    
            private ImageView mImageView;
    
            public BitmapWorkerTask(ImageView imageView) {
                mImageView = imageView;
            }
    
            // 在后台加载图片。
            @Override
            protected Bitmap doInBackground(String... params) {
                final Bitmap bitmap = decodeSampledBitmapFromResource(
                        params[0], 320, 320);
                addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
                return bitmap;
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                mImageView.setImageBitmap(bitmap);
            }
        }
    }
    
  • 相关阅读:
    VMWare Workstation的激活码 亲测有效
    虚拟机搭建appRtcDemo的appr.tc服务器
    windows webrtc支持H264的源码编译
    windows webrtc 编译
    获取windows系统分屏个数
    windows cmd窗口光标闪动效果消失
    win10 检测系统是不是正版的 以及slmgr.vbm -dlv命令不生效
    symfonos2
    利用ARP欺骗进行MITM(中间人攻击)
    内网学习之MySQL服务提权
  • 原文地址:https://www.cnblogs.com/china-soft/p/4921010.html
Copyright © 2011-2022 走看看