flutter 列表数据缓存和预加载

ListView等列表数据缓存管理

dart pub :https://pub.dev/packages/list_data_cache_manager
GitHub:https://github.com/LBXjixiangniao/list_data_cache_manager

目的

  • 列表数据量很多(几千或者过万)的时候进行本地数据缓存管理,以减少内存占有量。
  • 实现列表数据的预加载

主要原理

数据缓存管理.png
  • 红色部分为存储在内存中的数据
  • 绿色表示App正在使用的数据(包括屏幕上显示的和列表预加载的)
  • 缓存使用链表管理,以利于添加和删除数据
  • 链表中缓存的是以下对象:
class ListCacheItem<T> extends LinkedListEntry<ListCacheItem> {
  int index;
  ///列表中使用和数据库中存储的都是data数据
  T _data;
}
  • 列表中使用和数据库中存储的都是ListCacheItem中的_data数据
主要设计思路如上图所示。其流程如下:

(1) 从数据库请求首页数据,将数据转换成ListCacheItem存储到链表中的同时保存到本地数据库
(2) 列表往上滚动,当列表显示或者预加载的数据快到末尾的时候执行网络请求加载更多
(3) 将服务器返回的数据转换成ListCacheItem存储到链表末尾,并保存到数据库。同时删除链表头部不再被列表使用的数据
(4) 如果继续往上滚动,重复第(2)和第(3)步

(5)如果往下滚动,则判断列表使用的数据是否接近链表头部了,如果接近了就先往头部填充ListCacheItem(此时_data为空),然后从数据库加载对应的数据,得到数据后判断对应的ListCacheItem是否还在链表中,如果还在就将数据传递给对应的_data,同时判断数据是否正被列表使用(则正在被用于构建UI),如果正被列表使用就执行UI刷新操作。同时删除链表尾部不再被列表使用的数据

(6) 如果往上滚动,则逻辑类似步骤(5)或者步骤(2)

相关widget

  • 列表中的item要包裹在ListCacheBuilder

备注:mount的时候执行的_checkIndex方法是检查对应的ListCacheItem是否在链表范围内,如果超出了,则链表缓存数据要做处理,以保证列表正在使用的数据都在链表缓存中。设计该逻辑的原因是flutter中的列表会自动缓存部分widget,也就是列表滚动过程中,UI的显示不一定执行children的创建。为了准确知道当前列表显示那些数据,所以在mount的时候做检查判断。

其他优化:flutter性能优化实践 分帧layout和paint等技巧

推荐阅读更多精彩内容