安卓保存多张图片到本地

前言

本篇主要仿照Glide完成图片三级缓存(内存-磁盘-网络),此外,我还加了一个内存复用池,用来复用已经申请好内存空间的bitmap对象的复用,为啥要自己写个Glide呢?因为要定义自己的磁盘缓存规则,场景就是不同的用户保存到不同的磁盘文件中,来完成磁盘图片文件跟用户绑定上传的功能。

三级缓存

private ActiveCache activeCache; // 活动缓存
    private MemoryCache memoryCache; // 内存缓存
    private DiskLruCacheImpl diskLruCache; // 磁盘缓存
    private Set<WeakReference<Value>> reusablePool;//内存复用池

Glide在内存缓存中加了一层设计,就是分为活动缓存和内存缓存。内存缓存采用Lrucache来缓存尚未被GC回收的图片,活动缓存则是缓存正在使用的图片,内存缓存和活动缓存中的图片是互斥的,就是正在使用的图片不会在内存缓存中,在内存缓存中的图片不会在活动缓存,这就是Glide第一级缓存,内存缓存。
Glide缓存二之磁盘缓存,这里采用LruDiskCache,也是github开源的一个项目,这里重点介绍下,因为这里涉及到比较多的设计:
1.前面提到了内存复用池,自然从磁盘加载到内存中时,首先看看内存复用池是否有满足条件的内存区域可以使用:

 private boolean isBitmapReusable(Bitmap bitmap,int w,int h,int inSampleSize){
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT){
          //版本控制,这里必须要相等才能复用
            return bitmap.getWidth() == w && bitmap.getHeight() == h && inSampleSize==1;
        }

        if (inSampleSize > 1){
            w /= inSampleSize;
            h /= inSampleSize;
        }
        int byteCount = getBytesPerPixel(bitmap.getConfig());
        //复用的内存池必须大于或者等于从磁盘加载的图片文件的字节数
        return byteCount <= bitmap.getAllocationByteCount();
    }

缓存三之网络缓存,当内存和磁盘都未命中时,此时就要去加载外部资源,我这里只写了网络的情况,

if (responseCode == HttpURLConnection.HTTP_OK) {
                inputStream = httpURLConnection.getInputStream();
                byte[] inputStream2ByteArr = inputStream2ByteArr(inputStream);
                //TODO 网络上获取图片 模拟接收过程。

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
//如果直接decodeStream 的话,二次开启的时候返回的bitmap为空,这里转化为字节数组

                BitmapFactory.decodeByteArray(inputStream2ByteArr,0,inputStream2ByteArr.length,options);

                int w = options.outWidth;
                int h = options.outHeight;

                options.inSampleSize = caculateInsampleSize(w,h,80,80);

                options.inJustDecodeBounds = false;

                options.inMutable =true;//设置可变
                options.inBitmap = reusable;

                final Bitmap bitmap =  BitmapFactory.decodeByteArray(inputStream2ByteArr,0,inputStream2ByteArr.length,options);

options.inMutable =true,这个就是为了内存复用做准备,首先要设置图片可变才能复用,加载完成图片后,在调用diskLrucache.put(key,value)方法,这里可以把key缓存下来,这个key就是图片url经过加密后的字符串,在遍历key集合,就可以完成多图的保存了。

关于磁盘缓存地址选择

  public static File getDiskCacheDir(Context context, String uniqueName) {
        String cachePath;

        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {

            cachePath = context.getExternalCacheDir().getPath();

        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

这里做了个判断,是否有SD卡,有SD卡,才能储存到应用私有目录中去。

总结

写的比较简单,有问题的话可以留言,我在详细一些去介绍,网上的三级缓存太多了,这里参照Gilde来写,用法和Glide一样。

源码地址:https://github.com/doubizhu/Gildelib

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339