美文网首页
Android之图片三级缓存

Android之图片三级缓存

作者: 潜心之力 | 来源:发表于2018-01-02 15:59 被阅读0次

    一、内存缓存(一级)

    public class MemoryCacheUtils {

    存放图片的集合

    private HashMap<String,SoftReference<Bitmap>> mHashMap =new HashMap<>();

    设置一级缓存(原理)

    public void setMemoryCache(String url, Bitmap bitmap){

    SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);

    mHashMap.put(url,softReference);

    mLruCache.put(url,bitmap); 

    }

    获取一级缓存(原理)

    public Bitmap getMemoryCache(String url){

    SoftReference<Bitmap> softReference =mHashMap.get(url);

    if(softReference != null){

    Bitmap bitmap =softReference.get();

    return bitmap;

    }

    return null;

    return mLruCache.get(url);

    }

    }

    优化:使用LruCache算法(least recentlly used cache),告别软引用和弱引用,内部核心是通过算法实现缓存的大小控制,封装HashMap,使用更加方便简单。使用LruCache代替上述的HashMap。

    private LruCache<String,Bitmap> mLruCache;

    构造方法初始化LruCache

    public MemoryCacheUtils(){

    //获取虚拟机分配的最大内存,默认16M

     long maxMemory = Runtime.getRuntime().maxMemory();

    //参数是内存缓存上限

    mLruCache =new LruCache((int) (maxMemory/8)){

    @Override

     protected int sizeOf(String key, Bitmap value) {

    //获取单个对象占用字节数大小

    //int byteCount = value.getByteCount();

    //兼容低版本,一行字节数*总行数

      int byteCount =value.getRowBytes()*value.getHeight();

    //返回单个对象占用内存大小

     return byteCount;

    }

    };


    二、本地缓存(二级)

    public class LocalCacheUtils {

    需要存放本地缓存的目录路径

    String path = Environment.getExternalStorageDirectory().getAbsolutePath() +"/自定义/";

    设置本地缓存

    public void setLocalCache(String url, Bitmap bitmap) {

    File dir =new File(path);

    if (!dir.exists() || !dir.isDirectory()) {  // 不存在 或者 不是目录

    //创建此抽象路径名指定的目录 //dir.mkdir();

    //创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

     dir.mkdirs();

    }

    //url需要经过处理

      File file =new File(dir, url);

    //将图片压缩到本地

     try {

    //参数1是图片格式,参数2是压缩比(0-100),100代表不压缩,参数3是文件输出流   bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));

    }catch (FileNotFoundException e) {

    e.printStackTrace();

    }

    }

    获取本地缓存

    public Bitmap getLocalCache(String url) {

    //url需要经过处理

      try {

    File cacheFile =new File(path, url);

    if (cacheFile.exists()) {  //缓存存在

     Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile));

    return bitmap;

    }

    }catch (Exception e) {

    e.printStackTrace();

    }

    return null;

    }

    }


    三、网络缓存(三级)

    public class NetCacheUtils {

    private LocalCacheUtils mLocalCacheUtils;

    private MemoryCacheUtils mMemoryCacheUtils;

    public NetCacheUtils(MemoryCacheUtils memoryCacheUtils,LocalCacheUtils localCacheUtils) {

    mMemoryCacheUtils=memoryCacheUtils;

    mLocalCacheUtils=localCacheUtils;

    }

    获取网络图片

    public void getBitmapFromNet(ImageView imageView,String url){

     new BitmapTask().execute(imageView,url);

    }

    异步加载网络图片的内部类

    class BitmapTaskextends AsyncTask<Object,Void,Bitmap>{

    private ImageView mImageView;

    @Override

    protected void onPreExecute() { //预操作

    super.onPreExecute();

    }

    @Override

    protected Bitmap doInBackground(Object... params) {//耗时操作

    //根据异步加载时传入的参数顺序来获取参数

    mImageView = (ImageView) params[0];

    String url = (String) params[1];

    //防止网络慢时,控件与加载的图片显示不符(ListView)

    mImageView.setTag(url);

    //网络访问

    download(url);

    return null;

    }

    @Override

    protected void onPostExecute(Bitmap bitmap) {  //后续操作

    doInBackground返回的值作为参数传入本方法

     if(bitmap!=null){

    mImageView.setImageBitmap(bitmap);

    String url= (String)mImageView.getTag();

    写入本地缓存

    mLocalCacheUtils.setLocalCache(url,bitmap);

    写入内存缓存

     mMemoryCacheUtils.setMemoryCache(url,bitmap);

    }

    }

    }

    }


    四、三级缓存综合使用

    public class BitmapUtils {

    private NetCacheUtils mNetCacheUtils;

    private LocalCacheUtils mLocalCacheUtils;

    private MemoryCacheUtils mMemoryCacheUtils;

    public BitmapUtils(){

    mMemoryCacheUtils =new MemoryCacheUtils();

    mLocalCacheUtils =new LocalCacheUtils();

    mNetCacheUtils =new NetCacheUtils(mMemoryCacheUtils,mLocalCacheUtils);

    }

    通过优先级加载图片

    public void displayBitmap(ImageView imageView,String url){

    内存缓存

    Bitmap bitmap=mMemoryCacheUtils.getMemoryCache(url);

    if(bitmap!=null){

    imageView.setImageBitmap(bitmap);

    return;

    }

    本地缓存

    Bitmap bitmap1=mLocalCacheUtils.getLocalCache(url);

    if(bitmap1!=null){

    imageView.setImageBitmap(bitmap1);

    mMemoryCacheUtils.setMemoryCache(url,bitmap1);

    return;

    }

    网络缓存

    mNetCacheUtils.getBitmapFromNet(imageView,url);

    }

    }


    五、Android之四大引用

    简介:Java虚拟机存在栈和堆,栈存放变量,堆存放类,它们之间存在一种引用关系

    1、强引用:默认都是强引用,不会回收

    2、软引用:当内存不足时,垃圾回收器会考虑回收

    创建:SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);

    从软引用中取出:Bitmap bitmap =softReference.get();

    3、弱引用:当内存不足时,垃圾回收器更会考虑回收,

    4、虚引用:当内存不足时,垃圾回收器最先考虑回收

    5、垃圾:一些没有被引用的对象称之为垃圾

    相关文章

      网友评论

          本文标题:Android之图片三级缓存

          本文链接:https://www.haomeiwen.com/subject/fazfnxtx.html