那么在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());
},
),
问题答案:
一个简单的基于时间的缓存不需要太多代码。
这可能会帮助您。它使用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;
}
}
要从中获取数据MyModel
,UI只需调用getAllRecords()
。这将从内存中获取记录(即from
_allRecords
),或者触发刷新以进行HTTP调用并更新记录。缓存的数据将在30分钟后自动过期,并且如果您要强制刷新(例如,如果用户明确点击刷新按钮),则可以通过forceRefresh: true
。