Android图片三级缓存策略

首先简单说一下:
三级缓存有哪三级:
   1、网络缓存 从网络获取资源(异步加载)网络缓存, 不优先加载, 速度慢,浪费流量
    2、本地缓存 从本地获取数据(File存储)本地缓存, 次优先加载, 速度快
    3、内存缓存 从内存获取数据(LruCache) 内存缓存, 优先加载, 速度最快
好了,下面回归咱们的正题,直接代码搞起

本地缓存
public class LocalCacheUtils {
    private static final String CACHE_PATH= Environment.getExternalStorageDirectory().getAbsolutePath()+"/my/images";
    /**
     * 从本地读取图片
     * @param url
     */
    public Bitmap getBitmapFromLocal(String url){
        String fileName = null;//把图片的url当做文件名,并进行MD5加密
        try {
            File file=new File(CACHE_PATH,fileName);
            Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从网络获取图片后,保存至本地缓存
     * @param url
     * @param bitmap
     */
    public void setBitmapToLocal(String url,Bitmap bitmap){
        try {

            File file=new File(CACHE_PATH,url);

            //通过得到文件的父文件,判断父文件是否存在
            File parentFile = file.getParentFile();
            if (!parentFile.exists()){
                parentFile.mkdirs();
            }
            //把图片保存至本地
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
内存缓存
public class MemoryCacheUtils {
    private LruCache<String, Bitmap> mMemoryCache;
    public MemoryCacheUtils(){
        long maxMemory = Runtime.getRuntime().maxMemory()/8;//得到手机最大允许内存的1/8,即超过指定内存,则开始回收
        //需要传入允许的内存最大值,虚拟机默认内存16M,真机不一定相同
        mMemoryCache=new LruCache<String,Bitmap>((int) maxMemory){
            //用于计算每个条目的大小
            @Override
            protected int sizeOf(String key, Bitmap value) {
                int byteCount = value.getByteCount();
                return byteCount;
            }
        };
    }
    /**
     * 从内存中读图片
     * @param url
     */
    public Bitmap getBitmapFromMemory(String url) {
        //Bitmap bitmap = mMemoryCache.get(url);//1.强引用方法
          /*2.弱引用方法
          SoftReference<Bitmap> bitmapSoftReference = mMemoryCache.get(url);
          if (bitmapSoftReference != null) {
              Bitmap bitmap = bitmapSoftReference.get();
              return bitmap;
          }
          */
        if(url==null||"".equals(url)){
            return null;
        }
        Bitmap bitmap = mMemoryCache.get(url);

        return bitmap;

    }
    /**
     * 往内存中写图片
     * @param url
     * @param bitmap
     */
    public void setBitmapToMemory(String url, Bitmap bitmap) {
        //mMemoryCache.put(url, bitmap);//1.强引用方法
          /*2.弱引用方法
          mMemoryCache.put(url, new SoftReference<>(bitmap));
          */
        mMemoryCache.put(url,bitmap);
    }
}

网络缓存
public class NetCacheUtils {

    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;

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

    }
    /**
     * 从网络下载图片
     * @param ivPic 显示图片的imageview
     * @param url   下载图片的网络地址
     */
    public void getBitmapFromNet(ImageView ivPic, String url) {
        new BitmapTask().execute(ivPic, url);//启动AsyncTask

    }


    public void getBitmapFromNet(View ivPic, String url) {
        new BitmapTask_view().execute(ivPic, url);//启动AsyncTask

    }
    public Bitmap getBitmapFromNet(final String url) {
        //启动AsyncTask
        return null;
    }
    /**
     * AsyncTask就是对handler和线程池的封装
     * 第一个泛型:参数类型
     * 第二个泛型:更新进度的泛型
     * 第三个泛型:onPostExecute的返回结果
     */
    class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

        private ImageView ivPic;
        private String url;

        /**
         * 后台耗时操作,存在于子线程中
         * @param params
         * @return
         */
        @Override
        protected Bitmap doInBackground(Object[] params) {
            ivPic = (ImageView) params[0];
            url = (String) params[1];

            return downLoadBitmap(url);
        }

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

        /**
         * 耗时方法结束后执行该方法,主线程中
         * @param result
         */
        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                ivPic.setImageBitmap(result);
                System.out.println("从网络缓存图片啦.....");

                //从网络获取图片后,保存至本地缓存
                mLocalCacheUtils.setBitmapToLocal(url, result);
                //保存至内存中
                mMemoryCacheUtils.setBitmapToMemory(url, result);

            }
        }
    }
    /**
     * AsyncTask就是对handler和线程池的封装
     * 第一个泛型:参数类型
     * 第二个泛型:更新进度的泛型
     * 第三个泛型:onPostExecute的返回结果
     */
    @SuppressLint("NewApi")
    class BitmapTask_view extends AsyncTask<Object, Void, Bitmap> {

        private View ivPic;
        private String url;

        /**
         * 后台耗时操作,存在于子线程中
         * @param params
         * @return
         */
        @Override
        protected Bitmap doInBackground(Object[] params) {
            ivPic = (View) params[0];
            url = (String) params[1];

            return downLoadBitmap(url);
        }

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

        /**
         * 耗时方法结束后执行该方法,主线程中
         * @param result
         */
        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                //ivPic.setImageBitmap(result);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    //Android系统大于等于API16,使用setBackground
                    ivPic.setBackground(new BitmapDrawable(result));
                } else {
                    //Android系统小于API16,使用setBackground
                    ivPic.setBackgroundDrawable(new BitmapDrawable(result));
                }


                System.out.println("从网络缓存图片啦.....");

                //从网络获取图片后,保存至本地缓存
                mLocalCacheUtils.setBitmapToLocal(url, result);
                //保存至内存中
                mMemoryCacheUtils.setBitmapToMemory(url, result);

            }
        }
    }
    /**
     * 网络下载图片
     * @param url
     * @return
     */
    public Bitmap downLoadBitmap(String url) {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");

            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                //图片压缩
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize=2;//宽高压缩为原来的1/2
                options.inPreferredConfig=Bitmap.Config.ARGB_4444;

                //Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream(),null,options);
                Bitmap bitmap=BitmapFactory.decodeStream(conn.getInputStream());
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }catch (Exception e) {
        } finally {
            if(conn!=null){
                conn.disconnect();
            }
        }

        return null;
    }
}

另写一个类进行调用
public class MyBitmapUtils {

    private NetCacheUtils mNetCacheUtils;
    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;

    public MyBitmapUtils(){
        mMemoryCacheUtils=new MemoryCacheUtils();
        mLocalCacheUtils=new LocalCacheUtils();
        mNetCacheUtils=new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils);
    }
    public Bitmap getBitmap(String url){
        Bitmap bitmap=null;
        bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
        if(bitmap!=null){
            return bitmap;
        }
        bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
        if(bitmap!=null){
            mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
            return bitmap;
        }

        return bitmap;
    }
    public void disPlay(ImageView ivPic, String url) {
        Bitmap bitmap;
        //内存缓存
        bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
        if (bitmap!=null){
            ivPic.setImageBitmap(bitmap);
            Log.e("iamgecache","从内存获取图片啦.....--->"+url);
            return;
        }

        //本地缓存
        bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
        if(bitmap !=null){
            ivPic.setImageBitmap(bitmap);
            Log.d("iamgecache","从本地获取图片啦.....-->"+url);
            //从本地获取图片后,保存至内存中
            mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
            return;
        }
        //网络缓存
        mNetCacheUtils.getBitmapFromNet(ivPic,url);
        Log.d("iamgecache","从网络获取图片啦.....-->"+url);
    }


    @SuppressLint("NewApi")
    public void disPlay(View ivPic, String url) {
        Bitmap bitmap;
        //内存缓存
        bitmap=mMemoryCacheUtils.getBitmapFromMemory(url);
        if (bitmap!=null){
            //ivPic.setImageBitmap(bitmap);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                //Android系统大于等于API16,使用setBackground
                ivPic.setBackground(new BitmapDrawable(bitmap));
            } else {
                //Android系统小于API16,使用setBackground
                ivPic.setBackgroundDrawable(new BitmapDrawable(bitmap));

            }
            //ivPic.setBackground(new BitmapDrawable(bitmap));

            Log.d("iamgecache","从内存获取图片啦.....--->"+url);
            return;
        }

        //本地缓存
        bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
        if(bitmap !=null){
            //    ivPic.setImageBitmap(bitmap);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                //Android系统大于等于API16,使用setBackground
                ivPic.setBackground(new BitmapDrawable(bitmap));
            } else {
                //Android系统小于API16,使用setBackground
                ivPic.setBackgroundDrawable(new BitmapDrawable(bitmap));
            }
            //ivPic.setBackground(new BitmapDrawable(bitmap));


            Log.e("iamgecache","从本地获取图片啦.....-->"+url);
            //从本地获取图片后,保存至内存中
            mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
            return;
        }
        //网络缓存
        mNetCacheUtils.getBitmapFromNet(ivPic,url);
        //  ivPic.setBackground(new BitmapDrawable(bitmap));
        Log.e("iamgecache","从网络获取图片啦.....-->"+url);
    }
}

到这里就可以了,剩下就是在需要的activity的中调用,更多精彩内容大家可以看看我的公众号
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值