三级缓存

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

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

        mMemoryCache = new LruCache((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 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{

      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);
    }
}

你可能感兴趣的:(三级缓存)