Flutter图片缓存管理ImageCache原理分析

 更新时间:2022年12月12日 15:13:14   作者:WeninerIo  
这篇文章主要为大家介绍了Flutter图片缓存管理ImageCache原理分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

设计: 嗯? 这个图片点击跳转进详情再返回图片怎么变白闪一下呢?
产品: 是啊是啊! 一定是个bug
开发: 囧囧囧

在开发过程中, 也许你也遇到过这样一个场景. 进入一个页面后,前一个页面的图片都会闪白一下. 或者在列表中,加载很多列表项后,之前列表中的图片都需要重新加载.你有没有想过这一切的原因是什么呢?

没错! 它就是我们今天介绍的主人公 --- ImageCache

可能有些人对ImageCache还有些陌生, 我们在之前的章节有说过启动流程时Flutter runApp到渲染上屏,有介绍过其中PaintingBinding这个mixin类.带着探索的心我们先去看看PaintingBinding都做了 一些什么操作呢?

PaintingBinding

PaintingBinding在构造函数中,除了构建自身的实例.同时也构建了图片缓存的管理实例.也包括了着色器预热.

{
    _instance = this;
    // 创建了图片缓存管理
    _imageCache = createImageCache();
    shaderWarmUp?.execute();
}

着色器预热可能大部分人都没有接触过,我们只需要知道通过着色器预热,可以提高首次编译的速度即可.有兴趣可以看一下这篇文章着色器预热; 我们现在把目光重新聚焦到今天的主题, 也就是createImageCache()这里.可以看到它直接返回了一个ImageCache的对象. 这里我们暂且不谈ImageCache, 再去看看在PaintingBinding有没有和ImageCache相关的一些代码吧.

  @override
  void evict(String asset) {
    // 调用了rootBundle.evict(asset);
    // 也就是从缓存中移除这个key的资源
    super.evict(asset);
    // 清除所有已显示和不再用到的图片缓存
    imageCache.clear();
    // 清除所有实时引用的图片缓存
    imageCache.clearLiveImages();
  }

  @override
  void handleMemoryPressure() {
    // rootBundle.clear();
    // 当操作系统通知应用程序内存压力情况时调用。
    // 清除所有的图片资源
    super.handleMemoryPressure();
    imageCache.clear();
  }

可以看到, 基本上所有的引用都避不开内存问题. 也就是文章开头出现的bug. 那么,为什么会出现闪白呢? 有多种可能,有可能是系统感受到了内存压力调用了handleMemoryPressure() 方法,清除了图片缓存,或者在ImageCache中,达到了最大缓存,因此内部根据least-recently-used的原则回收了图片缓存.所以回头再看的时候,图片又重新加载了一遍.自然发生了闪白现象. 既然知道了原因,那么解决问题的方法:

  • 减少图片缓存
  • 增大图片缓存的阀值,让系统感觉到压力的阀值提升 我们来分别分析一下两者的可行性

减少图片缓存

如果要减少图片缓存, 我们要知道图片的内存是怎么计算的? 图片内存=分辨率*每个像素点大小 减少的方法也就出来了:

  • 减少分辨率
    也就是降低采样率.flutter中即cacheHeight和cacheWidth
  • 减少像素点大小
    这里也就是像素点的格式,ALPHA_8、RGB_565、ARGB_4444、ARGB_8888、RGBA_F16这些

增大阀值

这里需要去看一下ImageCache中.我们推断一下,什么情况下一个缓存池会达到阀值呢? 那一定是有新图片插入,所以总量才会提升才会够到阀值的门槛.我们找一下有没有相关的方法. 嗯哼~ 果然有一个_checkCacheSize

{
    ...
    // 只要当前的内存超标就会一直执行下去
    while (_currentSizeBytes > _maximumSizeBytes || _cache.length > _maximumSize) {
      // 根据least-recently-used这个逻辑去依次清除图片缓存
      final Object key = _cache.keys.first;
      final _CachedImage image = _cache[key]!;
      _currentSizeBytes -= image.sizeBytes!;
      image.dispose();
      _cache.remove(key);
    }
    ...
}

说明我们阀值取决于_maximumSizeBytes和_maximumSize, 一个负责最大缓存图片内存,一个负责最大缓存图片数. 也就是说我们更新这两个指就可以改变图片内存的阀值.从而减少内存回收的频率.

思考

很多问题的发生实际上源码中都有些提示, 带着问题去看收获的远远比单独阅读源码要有收获的多.
这里是weniner,一个在奋斗的flutter. 有些收获的话,不妨点个关注哦!

以上就是Flutter图片缓存管理ImageCache原理分析的详细内容,更多关于Flutter ImageCache的资料请关注脚本之家其它相关文章!

相关文章

  • Flutter学习之构建、布局及绘制三部曲

    Flutter学习之构建、布局及绘制三部曲

    这篇文章主要给大家介绍了关于Flutter学习之构建、布局及绘制三部曲的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Flutter具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • Android使用SharedPreferences存储数据的实现方法

    Android使用SharedPreferences存储数据的实现方法

    这篇文章主要介绍了Android使用SharedPreferences存储数据的实现方法,可实现针对短信的临时保存功能,非常简单实用,需要的朋友可以参考下
    2016-06-06
  • Android实现ListView异步加载的方法(改进版)

    Android实现ListView异步加载的方法(改进版)

    这篇文章主要介绍了Android实现ListView异步加载的方法,针对前面介绍的方法进行了线程操作的改进,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • android ListView结合xutils3仿微信实现下拉加载更多

    android ListView结合xutils3仿微信实现下拉加载更多

    本篇文章主要介绍了android ListView结合xutils3仿微信实现下拉加载更多,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Flutter实现切换应用时隐藏应用预览

    Flutter实现切换应用时隐藏应用预览

    如果您要显示敏感数据,例如钱包金额,或者只是当登录表单显示插入的密码清晰时,当您不在应用程序中时,您必须隐藏敏感数据。本文将利用Flutter实现切换应用时隐藏应用预览,需要的可以参考一下
    2022-06-06
  • Android中ScrollView实现滑动距离监听器的方法

    Android中ScrollView实现滑动距离监听器的方法

    ScrollView相信对每位Android开发者们来说都不陌生,所以这篇文章给大家主要介绍了Android中ScrollView实现滑动距离监听器的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-10-10
  • Android实现图片缓存与异步加载

    Android实现图片缓存与异步加载

    这篇文章主要为大家详细介绍了Android实现图片缓存与异步加载的相关资料,需要的朋友可以参考下
    2016-02-02
  • Android视频加水印之FFmpeg的简单应用实例

    Android视频加水印之FFmpeg的简单应用实例

    最近有个需求,需要录制视频,能添加水印,所以下面这篇文章主要给大家介绍了关于Android视频加水印之FFmpeg的简单应用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Android应用中绘制圆形头像的方法解析

    Android应用中绘制圆形头像的方法解析

    这篇文章主要介绍了Android应用中绘制圆形头像的方法解析,文后还顺带介绍了Android App常用图标尺寸规范,需要的朋友可以参考下
    2016-02-02
  • Android SQLite数据库基本操作方法

    Android SQLite数据库基本操作方法

    本篇文章主要介绍了Android SQLite数据库基本操作方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02

最新评论