Android Glide缓存策略分析

听课小知识:第三方库不要直接使用,封装后再用
前言:此篇我主要是想了解Glide缓存的封装机制,顺路看了看数据的取出过程,至于数据的存储,涉及网络层面暂时不分析了。磨刀不误砍柴工,感觉先把前三点理解透了,就很好看glide的源码了

1.内存缓存LruCache的使用

浅析LRUCache原理(Android)

2.硬盘缓存DisLruCache的使用

Android DiskLruCache完全解析,硬盘缓存的最佳方案

3.软弱引用的使用

Android 弱引用和软引用

4.Glide缓存策略

Glide 系列(四) Glide缓存机制
Glide缓存机制大致分为三层:内存缓存、弱引用缓存、磁盘缓存。
存的顺序是:弱引用、内存、磁盘
取的顺序是:内存、弱引用、磁盘
以下展示的是取的过程

//从内存中取数据
 EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
        if (cached != null) {
            cb.onResourceReady(cached);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Loaded resource from cache", startTime, key);
            }
            return null;
        }
        
//从弱引用中取数据
        EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
        if (active != null) {
            cb.onResourceReady(active);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Loaded resource from active resources", startTime, key);
            }
            return null;
        }
//从磁盘中取  
        EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
        DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
                transcoder, diskCacheProvider, diskCacheStrategy, priority);
        EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
        jobs.put(key, engineJob);
        engineJob.addCallback(cb);
        engineJob.start(runnable);

看loadFromCache方法中显示,当cached有值的时候,将数据存进了activeResources中

private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {
        if (!isMemoryCacheable) {
            return null;
        }

        EngineResource<?> cached = getEngineResourceFromCache(key);
        if (cached != null) {
            cached.acquire();
            activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
        }
        return cached;
    }

接着看getEngineResourceFromCache()方法中的第一行代码,内存中删除了要取出的值

private EngineResource<?> getEngineResourceFromCache(Key key) {
//Removes the value for the given key and returns it if present or null otherwise.
        Resource<?> cached = cache.remove(key);

        final EngineResource result;
        if (cached == null) {
            result = null;
        } else if (cached instanceof EngineResource) {
            // Save an object allocation if we've cached an EngineResource (the typical case).
            result = (EngineResource) cached;
        } else {
            result = new EngineResource(cached, true /*isCacheable*/);
        }
        return result;
    }

所以当发现内存中有值的时候,是先存进弱引用中,然后再查找弱引用显示图片,弱引用中没有图片的话再去硬盘中找。
Tip:采用弱引用的方式是为了防止内存泄漏

内存缓存

1.关键类
LruResourceCache 内部存储的相关方法类
MemoryCache 内部存储方法接口
Engine 统领内存相关操作的类
2.封装机制
内存缓存的封装机制很简单,找到这个类,你也就明白了

硬盘缓存

1.相关类
DiskLruCacheWrapper 磁盘存储相关方法类
DiskLruCacheFactory 获得以上实例的工厂类
ExternalCacheDiskCacheFactory 返回外部存储文件地址
InternalCacheDiskCacheFactory 返回内部存储文件地址
DecodeJob 对硬盘存储方法的进一步封装
2.封装机制
硬盘缓存相当于封装了两层,第一层是基础存储层,第二层相当于业务层,就是根据存储的需要进行存储

喵语:感觉有很多不到位的地方,还有很多没有看明白的地方,如果写的有什么错误,欢迎大神指出

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 【Android 库 Glide】 引用 Android图片加载框架最全解析(一),Glide的基本用法Andro...
    Rtia阅读 5,616评论 0 22
  • Android缓存机制:如果没有缓存,在大量的网络请求从远程获取图片时会造成网络流量的浪费,加载速度较慢,用户体验...
    芒果味的你呀阅读 4,553评论 13 22
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,174评论 1 32
  • 你在通那边 意味着有形的距离 不能轻易消除 当我望着门前的马路 我也明白 还是可以通过去 但是你在通那边! 多少不...
    陈果_周绿阅读 207评论 0 0
  • by维尼 本人外地矮穷挫一枚,五年前机缘巧合地来到了魔都念书,和多数当代大学生一样,象牙塔里念书是假,逍遥是真,荒...
    e3f105af39ac阅读 2,715评论 34 45