那么在 Flutter 中缓存最简单的方法是什么?

Hoo*_*yar 8 dart flutter

该应用程序是一个简单的新闻阅读器,它显示 WordPress 帖子,没什么特别的,不使用 BLOC、继承的 Widget、Firebase。我希望它即使在用户离线时也能显示缓存的数据(这是最新的 10 个帖子)。

所以如果用户离线显示缓存数据;或者以某种方式默认数据是缓存数据。

从 WP REST API 获取 firstPost[Id] 如果缓存的 Json 文件包含 Post[id],则显示缓存的数据;否则 getPosts(); 并显示加载指示器。还请更新本地 JSON 文件。

获取JSON数据的代码:

// Function to fetch list of posts
 Future<String> getPosts() async {
 var res = await http
    .get(Uri.encodeFull(apiUrl + "posts?_embed&per_page=10"), //TODO make it unlimited
        headers: {"Accept": "application/json"});

setState(() {
  var resBody = json.decode(res.body);

  posts = resBody;
});

return "Success!";
}
Run Code Online (Sandbox Code Playgroud)

获取帖子并显示加载指示器的未来:

  body: FutureBuilder<List<String>>(
      future: getPosts(),
      builder: (context, snapshot) {
        if (snapshot.hasError) print(snapshot.error);

        return snapshot.hasData
            ? ListViewPosts(posts: snapshot.data)
            : Center(child: CircularProgressIndicator());
      },
    ),
Run Code Online (Sandbox Code Playgroud)

Mag*_*s W 17

一个简单的基于时间的缓存不需要太多代码。

这可能会帮助你。它使用ScopedModel,但它也可以很容易地成为一个简单的类,尽管notifyListeners()如果您希望模型触发 UI 的刷新,则必须删除调用或将其替换为您自己的机制。

class MyModel extends Model{
    Duration _cacheValidDuration;
    DateTime _lastFetchTime;
    List<MyRecord> _allRecords;



    MyModel(){
        _cacheValidDuration = Duration(minutes: 30);
        _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(0);
        _allRecords = [];
    }



    /// Refreshes all records from the API, replacing the ones that are in the cache.
    /// Notifies listeners if notifyListeners is true.
    Future<void> refreshAllRecords(bool notifyListeners) async{
        _allRecords = await MyApi.getAllRecords(); // This makes the actual HTTP request
        _lastFetchTime = DateTime.now();
        if( notifyListeners ) this.notifyListeners();
    }


    /// If the cache time has expired, or forceRefresh is true, records are refreshed from the API before being returned.
    /// Otherwise the cached records are returned.
    Future<List<MyRecord>> getAllRecords({bool forceRefresh = false}) async{
        bool shouldRefreshFromApi = (null == _allRecords || _allRecords.isEmpty || null == _lastFetchTime || _lastFetchTime.isBefore(DateTime.now().subtract(_cacheValidDuration)) || forceRefresh);

        if( shouldRefreshFromApi )
           await refreshAllRecords(false);

        return _allRecords;
    }
}
Run Code Online (Sandbox Code Playgroud)

要从中获取数据MyModel,UI 只需调用getAllRecords(). 这将从内存中获取记录(即 from _allRecords)或触发刷新,从而进行 HTTP 调用并更新记录。缓存的数据会在 30 分钟后自动过期,如果您想强制刷新(例如,如果用户明确点击刷新按钮),您可以通过forceRefresh: true.