Glide的三级缓存

其实对于glide 的三级缓存分为:内存缓存,本地缓存和网络缓存。

为什么需要进行三级缓存呢?

因为android默认给每一个应用分配16M的内存,如果加载过多的图片的话,为了防止内存溢出(其实要区分一下内存泄漏的概念)。

三级缓存的具体实现:

1.网络缓存

 根据图片的url去加载图片
    在本地和内存中缓存

    public class NetCacheUtils {

        private LocalCacheUtils mLocalCacheUtils;
        private MemoryCacheUtils mMemoryCacheUtils;

        public NetCacheUtils(LocalCacheUtils localCacheUtils,
                MemoryCacheUtils memoryCacheUtils) {
            mLocalCacheUtils = localCacheUtils;
            mMemoryCacheUtils = memoryCacheUtils;
        }

        /**
         * 从网络下载图片
         * 
         * @param ivPic
         * @param url
         */
        public void getBitmapFromNet(ImageView ivPic, String url) {
            new BitmapTask().execute(ivPic, url);// 启动AsyncTask,
                                                    // 参数会在doInbackground中获取
        }

        /**
         * Handler和线程池的封装
         * 
         * 第一个泛型: 参数类型 第二个泛型: 更新进度的泛型, 第三个泛型是onPostExecute的返回结果
         * 
         * 
         */
        class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

            private ImageView ivPic;
            private String url;

            /**
             * 后台耗时方法在此执行, 子线程
             */
            @Override
            protected Bitmap doInBackground(Object... params) {
                ivPic = (ImageView) params[0];
                url = (String) params[1];

                ivPic.setTag(url);// 将url和imageview绑定

                return downloadBitmap(url);
            }

            /**
             * 更新进度, 主线程
             */
            @Override
            protected void onProgressUpdate(Void... values) {
                super.onProgressUpdate(values);
            }

            /**
             * 耗时方法结束后,执行该方法, 主线程
             */
            @Override
            protected void onPostExecute(Bitmap result) {
                if (result != null) {
                    String bindUrl = (String) ivPic.getTag();

                    if (url.equals(bindUrl)) {// 确保图片设定给了正确的imageview
                        ivPic.setImageBitmap(result);
                        mLocalCacheUtils.setBitmapToLocal(url, result);// 将图片保存在本地
                        mMemoryCacheUtils.setBitmapToMemory(url, result);// 将图片保存在内存
                        System.out.println("从网络缓存读取图片啦...");
                    }
                }
            }
        }

        /**
         * 下载图片
         * 
         * @param url
         * @return
         */
        private Bitmap downloadBitmap(String url) {

            HttpURLConnection conn = null;
            try {
                conn = (HttpURLConnection) new URL(url).openConnection();

                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.setRequestMethod("GET");
                conn.connect();

                int responseCode = conn.getResponseCode();
                if (responseCode == 200) {
                    InputStream inputStream = conn.getInputStream();

                    //图片压缩处理
                    BitmapFactory.Options option = new BitmapFactory.Options();
                    option.inSampleSize = 2;//宽高都压缩为原来的二分之一, 此参数需要根据图片要展示的大小来确定
                    option.inPreferredConfig = Bitmap.Config.RGB_565;//设置图片格式

                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, option);
                    return bitmap;
                }

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                conn.disconnect();
            }

            return null;
        }
    }

本地缓存:

1.两个方法:设置本地缓存,以及获取本地缓存

 
 
  • 1
  • 2
public class LocalCacheUtils {

        public static final String CACHE_PATH = Environment
                .getExternalStorageDirectory().getAbsolutePath() + "/local_cache";

        /**
         * 从本地sdcard读图片
         */
        public Bitmap getBitmapFromLocal(String url) {
            try {
                String fileName = MD5Encoder.encode(url);
                File file = new File(CACHE_PATH, fileName);

                if (file.exists()) {
                    Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(
                            file));
                    return bitmap;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * 向sdcard写图片
         * 
         * @param url
         * @param bitmap
         */
        public void setBitmapToLocal(String url, Bitmap bitmap) {
            try {
                String fileName = MD5Encoder.encode(url);

                File file = new File(CACHE_PATH, fileName);

                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {// 如果文件夹不存在, 创建文件夹
                    parentFile.mkdirs();
                }

                // 将图片保存在本地
                bitmap.compress(CompressFormat.JPEG, 100,
                        new FileOutputStream(file));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

内存缓存

两个方法:设置内存缓存,获取内存缓存。

问题:

如果使用hashmap去存储图片时,当图片越来越多,那么会造成内存溢出,因为是强引用(对于强引用的系统不会回收)

如果改成软引用softReference,在android 2.3 以上的系统,对象会被提前回收。

解决的办法:

可以用LruCache来解决上述内存不回收或提前回收的问题。least recentlly use 最少最近使用算法 它会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定(这个东西没有用过..)
 public class MemoryCacheUtils {

            // private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new
            // HashMap<String, SoftReference<Bitmap>>();
            private LruCache<String, Bitmap> mMemoryCache;

            public MemoryCacheUtils() {
                long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模拟器默认是16M
                mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
                    @Override
                    protected int sizeOf(String key, Bitmap value) {
                        int byteCount = value.getRowBytes() * value.getHeight();// 获取图片占用内存大小
                        return byteCount;
                    }
                };
            }

            /**
             * 从内存读
             * 
             * @param url
             */
            public Bitmap getBitmapFromMemory(String url) {
                // SoftReference<Bitmap> softReference = mMemoryCache.get(url);
                // if (softReference != null) {
                // Bitmap bitmap = softReference.get();
                // return bitmap;
                // }
                return mMemoryCache.get(url);
            }

            /**
             * 写内存
             * 
             * @param url
             * @param bitmap
             */
            public void setBitmapToMemory(String url, Bitmap bitmap) {
                // SoftReference<Bitmap> softReference = new
                // SoftReference<Bitmap>(bitmap);
                // mMemoryCache.put(url, softReference);
                mMemoryCache.put(url, bitmap);
            }
        }


转载出处:http://blog.csdn.net/sinat_20645961/article/details/46325243

猜你喜欢

转载自blog.csdn.net/god_sunht/article/details/79150716