三级缓存

内存缓存
Java中对象的四种引用类型介绍

 强引用
  Java中所有实例化的对象都是强引用类型,回收时GC宁愿抛出OOM异常,也不愿回收它。
  软引用 SoftReference
  内存足够时,不回收。内存不够时,就回收。内存缓存就是使用这种方式缓存对象
  弱引用 WeakReference
  GC一出来工作就回收它
  虚引用 PhantomReference
  用完就消失

//MD5Utils

public class MD5Utils {


    public static String getMD5Str(String str)
    {
        MessageDigest messageDigest = null;
        try
        {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e)
        {
            System.out.println("NoSuchAlgorithmException caught!");
            System.exit(-1);
        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        byte[] byteArray = messageDigest.digest();

        StringBuffer md5StrBuff = new StringBuffer();

        for (int i = 0; i < byteArray.length; i++)
        {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
            else
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return md5StrBuff.toString();
    }
}

//内存
public class MemoryCacheUtils {


    /*实现方法:
通过 HashMap<String,Bitmap>键值对的方式保存图片,key为地址,value为图片对象,但因是强引用对象,很容易造成内存溢出,可以尝试SoftReference软引用对象
通过 HashMap<String, SoftReference<Bitmap>>SoftReference 为软引用对象(GC垃圾回收会自动回收软引用对象),但在Android2.3+后,系统会优先考虑回收弱引用对象,官方提出使用LruCache
通过 LruCache<String,Bitmap> least recentlly use 最少最近使用算法
会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定
*/
    private LruCache<String, Bitmap> mMemoryCache;

    public MemoryCacheUtils(){
        long maxMemory  = Runtime.getRuntime().maxMemory()/8;

        mMemoryCache = new LruCache<String,Bitmap>((int)maxMemory){
            @Override
            protected int sizeOf(String key, Bitmap value) {
               int byteCount = value.getByteCount();
               return byteCount;
            }
        };
    }

    //从内存中读图片
    public Bitmap getBitmapFormMemory(String url){

        //Bitmap bitmap = mMemoryCache.get(url);//1.强引用方法
            /*2.弱引用方法
            SoftReference<Bitmap> bitmapSoftReference = mMemoryCache.get(url);
            if (bitmapSoftReference != null) {
                Bitmap bitmap = bitmapSoftReference.get();
                return bitmap;
            }
            */

        Bitmap bitmap = mMemoryCache.get(url);
        return 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 LocalCacheUtils {
    private static final String CACHE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();

    //从本地读取图片

    public Bitmap getBitmapFromLocal(String url){
        String fileName = null;

        fileName = MD5Utils.getMD5Str(url);

        File file = new File(CACHE_PATH, fileName);

        try {
            Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
            return bitmap;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }


    //从网络获取图片后,保存至本地缓存

    public void setBitmapToLocal(String url,Bitmap bitmap){

        String fileName = MD5Utils.getMD5Str(url);

        File file = new File(CACHE_PATH, fileName);

        File parentFile = file.getParentFile();

        if(parentFile!=null){
            parentFile.mkdir();
        }

        //把图片保存至本地
        try {
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

//网络

public class NetCacheUtils {

  private LocalCacheUtils mLocalCacheUtils;
  private MemoryCacheUtils mMemoryCacheUtils;
  private static final String TAG = "NetCacheUtils";

  public NetCacheUtils(LocalCacheUtils mLocalCacheUtils, MemoryCacheUtils mMemoryCacheUtils) {
      this.mLocalCacheUtils = mLocalCacheUtils;
      this.mMemoryCacheUtils = mMemoryCacheUtils;
  }

  public void getBitmapForNet(ImageView imageView,String url){
      new BitmapTask().execute(imageView,url);
  }

  class BitmapTask extends AsyncTask<Object,Void, Bitmap>{

      private ImageView imageView;
      private String url;

      @Override
      protected Bitmap doInBackground(Object... objects) {

          imageView = (ImageView) objects[0];
          url = (String)objects[1];
          return downLoadBitmap(url);
      }

      @Override
      protected void onPostExecute(Bitmap bitmap) {
          if(bitmap!=null){
              imageView.setImageBitmap(bitmap);

              Log.i(TAG, "onPostExecute: 网络进行下载图片");


              //本地 内存中 分别 存入一份
              mLocalCacheUtils.setBitmapToLocal(url,bitmap);

              mMemoryCacheUtils.setBitmapToMemory(url,bitmap);
          }
          super.onPostExecute(bitmap);
      }

      private Bitmap downLoadBitmap(String url){
          HttpURLConnection connection = null;

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

              connection.setRequestMethod("GET");

              if(connection.getResponseCode()==200){
                  //图片压缩
                  BitmapFactory.Options options = new BitmapFactory.Options();
                  options.inSampleSize=0;
                  options.inPreferredConfig=Bitmap.Config.ARGB_4444;
                  Bitmap bitmap = BitmapFactory.decodeStream(connection.getInputStream(), null, options);
                  return bitmap;
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
          return null;
      }
  }
}

//使用

public class MyBitmapUtils {
    private NetCacheUtils mNetBitmapUtils;
    private LocalCacheUtils mLocalCacheUtils;
    private MemoryCacheUtils mMemoryCacheUtils;

    private static final String TAG = "MyBitmapUtils";
    public MyBitmapUtils(){
        mLocalCacheUtils = new LocalCacheUtils();
        mMemoryCacheUtils = new MemoryCacheUtils();
        mNetBitmapUtils = new NetCacheUtils(mLocalCacheUtils,mMemoryCacheUtils);
    }

    public void disPlay(ImageView imageView,String url){
        imageView.setImageResource(R.mipmap.ic_launcher_round);

        Bitmap bitmap;
        bitmap = mMemoryCacheUtils.getBitmapFormMemory(url);

        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            Log.i(TAG, "disPlay: 从内存中获取图片了");
            return;
        }

        bitmap = mLocalCacheUtils.getBitmapFromLocal(url);
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            Log.i(TAG, "disPlay: 从本地获取图片了");
            return;
        }

        Log.i(TAG, "disPlay: 来过");
        mNetBitmapUtils.getBitmapForNet(imageView,url);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,887评论 1 32
  • LruCache 缓存介绍 一、Android中缓存的必须要性   在平时业务中,对于缓存特别的重视,是优化的重要...
    一只胖胖胖胖猿阅读 3,297评论 0 0
  • 介绍 本文介绍了三级缓存的原理及操作,并且用策略模式的架子框起来。 1.图片的三级缓存是什么 图片的三级缓存顾名思...
    虫儿飞ZLEI阅读 4,948评论 0 6
  • 图片的三级缓存机制一般是指应用加载图片的时候,分别去访问内存,文件和网络而获取图片数据的一种行为。以下内容只是简单...
    笑说余生阅读 13,304评论 5 59
  • 三级缓存概览引入 我们之所以要做缓存,主要是为了提高效率,节省流量。但是为什么要做三级呢?为什么不只存在内存或者只...
    路_a783阅读 5,990评论 2 11

友情链接更多精彩内容