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

时间:2018-11-24 15:31:13

标签: 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!";
}

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

  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());
      },
    ),

4 个答案:

答案 0 :(得分:2)

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

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

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;
    }
}

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

答案 1 :(得分:1)

另一种缓存方式是使用hive No-SQL数据库,它可以更快地检索文档并且易于使用。当用户上线时,只需刷新配置单元中的数据即可

有关更多详细信息,请检查:https://github.com/shashiben/Anime-details以了解如何使用配置单元进行缓存

答案 2 :(得分:-1)

我认为这不是最好的方法,但是它可以工作。 应用每次启动时,都会向用户显示最新的缓存帖子(如果存在)。 然后它会检查是否有新帖子可用,如果找到,则将删除数据库,并使用新数据创建一个新帖子。

答案 3 :(得分:-1)

在经历了许多缓存解决方案之后,我学到了以下内容(按复杂度排序):

1-使用共享首选项 2-使用配置单元数据库 3-使用Firestore离线服务 4-使用sqflite