Java 缓存的种类和获取方式

发布于 2024-10-07 10:24:44 字数 3248 浏览 7 评论 0

public class Engine implements EngineJobListener,
        MemoryCache.ResourceRemovedListener,
        EngineResource.ResourceListener {

    private final MemoryCache cache;
    private final Map<Key, WeakReference<EngineResource<?>>> 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;
    }

    private EngineResource<?> getEngineResourceFromCache(Key key) {
        Resource<?> cached = cache.remove(key);
        final EngineResource result;
        if (cached == null) {
            result = null;
        } else if (cached instanceof EngineResource) {
            result = (EngineResource) cached;
        } else {
            result = new EngineResource(cached, true /*isCacheable*/);
        }
        return result;
    }

    private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {
        if (!isMemoryCacheable) {
            return null;
        }
        EngineResource<?> active = null;
        WeakReference<EngineResource<?>> activeRef = activeResources.get(key);
        if (activeRef != null) {
            active = activeRef.get();
            if (active != null) {
                active.acquire();
            } else {
                activeResources.remove(key);
            }
        }
        return active;
    }

    ...
}
  • loadFromCache()
    • LRUCache
  • loadFromActiveResources()
    • activeResources 就是一个弱引用的 HashMap,用来缓存正在使用中的图片

loadFromActiveResources() 方法就是从 activeResources 这个 HashMap 当中取值的。使用 activeResources 来缓存正在使用中的图片,可以保护这些图片不会被 LruCache 算法回收掉。

ActiveCache、MemoryCache、BitmapPool

三者的缓存关系如下:

  1. 在加载图片时,先去 MemoryCache 中查找图片,找到缓存后,将它移入 ActiveCache,并将引用数量加 1。
  2. 当 View 复用的时候,如果原先的 ImageView 已经绑定了 EngineResource,就需要调用 EnginerResource 的 release 方法,该方法会判断该 Resource 的引用数量是否为 0,如果为 0,就对资源进行释放。
  3. 第 2 步 Resource 引用数量为 0 时,将 Resource 从 ActiveResource 中移除,并加入 MemoryCache 中,以供下次使用。
  4. 当 MemoryCache 达到上限的时候,将里面最近未使用的 Bitmap 移除到 BitmapPool 中,用来做 Bitmap 复用,防止内存抖动。
  5. 当 ActiveCache 或者 MemoryCache 中都没有指定图片时,就从磁盘缓存或者网络加载。
  6. 内存缓存没有时,先从磁盘缓存加载,加载到原始数据后利用 BitmapPool 中可以复用的 Bitmap 进行图片复用,加载成功后回调 ResourceCallback 的 onResourceReady 进行回调,回调里面将原始资源组装成 EngineResource,并将 Resource 加入 ActiveResource。
  7. 从网络获取的时候,会将网络数据缓存到本地,其余过程和 6 一样

硬盘缓存

  • DiskCacheStrategy.NONE: 表示不缓存任何内容。
  • DiskCacheStrategy.SOURCE: 表示只缓存原始图片。
  • DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)。
  • DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。

当我们使用 Glide 去加载一张图片的时候,Glide 默认并不会将原始图片展示出来,而是会对图片进行压缩和转换。总之就是经过种种一系列操作之后得到的图片,就叫转换过后的图片。而 Glide 默认情况下在硬盘缓存的就是转换过后的图片,我们通过调用 diskCacheStrategy() 方法则可以改变这一默认行为。 因此不同尺寸的同一图片也会被缓存多次

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

二智少女

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

謌踐踏愛綪

文章 0 评论 0

开始看清了

文章 0 评论 0

高速公鹿

文章 0 评论 0

alipaysp_PLnULTzf66

文章 0 评论 0

热情消退

文章 0 评论 0

白色月光

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文