Flutter网络请求与缓存插件dio_http_cache_thmoises的使用
Flutter网络请求与缓存插件dio_http_cache_thmoises的使用
dio-http-cache
Dio-http-cache 是一个用于 Dio (Flutter 的 HTTP 客户端) 的缓存库,类似于 Android 中的 RxCache。
Dio-http-cache 使用 sqflite 作为磁盘缓存,并采用 LRU 策略作为内存缓存。
受 flutter_cache_manager 启发。
添加依赖
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
dio_http_cache_thmoises: ^1.0.x #最新版本
快速开始
1. 在 Dio 中添加 dio-http-cache 拦截器
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: "http://www.google.com")).interceptor);
2. 设置请求的最大缓存时间
Dio().get(
"http://www.google.com",
options: buildCacheOptions(Duration(days: 7)), // 缓存时间为7天
);
高级用法
1. 自定义配置(通过 buildCacheOptions
)
a. primaryKey
默认情况下,host + path
作为主键。你可以自定义它。
buildCacheOptions(Duration(days: 7), primaryKey: "customKey")
b. subKey
默认情况下,查询参数(data
或 queryParameters
)作为子键。必要时可以指定子键。
buildCacheOptions(Duration(days: 7), subKey: "page=1")
c. maxAge
设置缓存的有效期。如果值为 null
或未设置,则会尝试从响应头中获取 maxAge
和 maxStale
。
buildCacheOptions(Duration(days: 7), maxAge: Duration(days: 3))
d. maxStale
设置过期时间。在 maxStale
时间内,即使请求失败或无网络连接,也会尝试返回缓存数据。
buildCacheOptions(Duration(days: 7), maxStale: Duration(days: 10))
e. forceRefresh
默认值为 false
。当设置为 true
时,优先从网络获取数据,失败后才尝试从缓存中读取。
buildCacheOptions(Duration(days: 7), forceRefresh: true)
- 从网络获取数据。
- 如果成功,更新缓存。
- 如果失败或无网络,尝试从缓存中读取。
2. 使用 CacheConfig
配置默认参数
a. baseUrl
可选。如果不设置 baseUrl
,在调用 deleteCache
时需要提供完整的路径,例如 "https://www.google.com/search?q=hello"
,而不是只提供 "search?q=hello"
。
CacheConfig(baseUrl: "https://www.example.com")
b. encrypt
和 decrypt
这两个方法必须一起使用来加密磁盘上的缓存数据,也可以在这里压缩数据。
CacheConfig(
encrypt: encryptFunction,
decrypt: decryptFunction,
)
c. defaultMaxAge
和 defaultMaxStale
默认值分别为 Duration(days: 7)
。
CacheConfig(defaultMaxAge: Duration(days: 3), defaultMaxStale: Duration(days: 10))
d. databasePath
和 databaseName
数据库的路径和名称。
CacheConfig(databasePath: "/path/to/db", databaseName: "my_cache.db")
e. skipMemoryCache
和 skipDiskCache
默认值均为 false
。
CacheConfig(skipMemoryCache: true, skipDiskCache: true)
f. maxMemoryCacheCount
默认值为 100
。
CacheConfig(maxMemoryCacheCount: 200)
g. defaultRequestMethod
默认值为 "POST"
,用于 delete caches
。
CacheConfig(defaultRequestMethod: "GET")
h. diskStore
自定义磁盘存储。
CacheConfig(diskStore: CustomDiskStore())
3. 如何清理过期缓存
a. 自动清理
无需手动操作,这是自动完成的。
b. 手动清理
DioCacheManager.clearExpired();
4. 如何删除缓存
a. 删除匹配主键的本地缓存
_dioCacheManager.deleteByPrimaryKey(path, requestMethod: "POST");
b. 删除匹配主键和子键的本地缓存
_dioCacheManager.deleteByPrimaryKeyAndSubKey(path, requestMethod: "GET");
// 如果有额外参数,必须一起传递
_dio.get(_url, queryParameters: {'k': keyword},
options: buildCacheOptions(Duration(hours: 1)));
// 删除缓存
_dioCacheManager.deleteByPrimaryKeyAndSubKey(_url, requestMethod: "GET", queryParameters: {'k': keyword});
_dio.post(_url, data: {'k': keyword},
options: buildCacheOptions(Duration(hours: 1)));
// 删除缓存
_dioCacheManager.deleteByPrimaryKeyAndSubKey(_url, requestMethod: "POST", data: {'k': keyword});
c. 删除指定主键和可选子键的本地缓存
_dioCacheManager.delete(primaryKey, {subKey, requestMethod});
5. 如何清空所有缓存(过期或未过期)
_dioCacheManager.clearAll();
6. 如何判断数据是否来自缓存
if (null != response.headers.value(DIO_CACHE_HEADER_KEY_DATA_SOURCE)) {
// 数据来自缓存
} else {
// 数据来自网络
}
示例:maxAge
和 maxStale
_dio.post(
"https://www.example.com",
data: {'k': "keyword"},
options: buildCacheOptions(
Duration(days: 3),
maxStale: Duration(days: 7),
)
)
- 0 ~ 3 天:直接从缓存中返回数据(与网络无关)。
- 3 ~ 7 天:
- 先从网络获取数据。
- 如果成功,刷新缓存。
- 如果失败或无网络,尝试从缓存中读取。
- 7 天以后:不再使用缓存,缓存会在适当时候被删除。
许可证
Copyright 2019 Hurshi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
示例代码
以下是完整的示例代码:
import 'package:flutter/material.dart';
import 'panels/cache_manage.dart';
import 'panels/panel_204.dart';
import 'panels/panel_get.dart';
import 'panels/panel_get_bytes.dart';
import 'panels/panel_get_from_service.dart';
import 'panels/panel_post.dart';
import 'tuple.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
final title = "DioHttpCache Example";
return MaterialApp(
title: title,
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(title: title));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
enum Panel { CACHE_MANAGER, POST, POST_204, GET_FROM_SERVICE, GET, GET_BYTES }
class _MyHomePageState extends State<MyHomePage> {
Panel panel = Panel.POST;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title!),
actions: <Widget>[_buildHomePageActionButtons(context)]),
body: getPanel());
}
Widget? getPanel() {
switch (panel) {
case Panel.CACHE_MANAGER:
return CacheManagerPanel();
case Panel.GET:
return GetPanel();
case Panel.POST:
return PostPanel();
case Panel.POST_204:
return Post204Panel();
case Panel.GET_FROM_SERVICE:
return PostGetLetServicePanel();
case Panel.GET_BYTES:
return GetBytesPanel();
}
}
Widget _buildHomePageActionButtons(BuildContext context) {
List<Pair<String, Function()>> choices = [
Pair("Cache Manager", () => setState(() => panel = Panel.CACHE_MANAGER)),
Pair("POST", () => setState(() => panel = Panel.POST)),
Pair("POST 204", () => setState(() => panel = Panel.POST_204)),
Pair("GET", () => setState(() => panel = Panel.GET)),
Pair("GET from service",
() => setState(() => panel = Panel.GET_FROM_SERVICE)),
Pair("GET byte array", () => setState(() => panel = Panel.GET_BYTES)),
];
return PopupMenuButton<Pair<String, Function()>>(
onSelected: (p) => p.i1!(),
child: Padding(
padding: EdgeInsets.all(10),
child: Icon(Icons.menu, color: Colors.white)),
itemBuilder: (BuildContext context) =>
choices
.map((choice) => PopupMenuItem<Pair<String, Function()>>(value: choice, child: Text(choice.i0!)))
.toList());
}
}
更多关于Flutter网络请求与缓存插件dio_http_cache_thmoises的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络请求与缓存插件dio_http_cache_thmoises的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dio_http_cache_thmoises
是一个基于 dio
的网络请求缓存插件,它可以帮助你在 Flutter 应用中轻松地管理网络请求的缓存。通过这个插件,你可以控制缓存的有效期、缓存策略等,从而提高应用的性能和用户体验。
安装
首先,你需要在 pubspec.yaml
文件中添加 dio_http_cache_thmoises
插件的依赖:
dependencies:
flutter:
sdk: flutter
dio: ^4.0.0
dio_http_cache_thmoises: ^1.0.0
然后运行 flutter pub get
来安装依赖。
基本用法
- 初始化 Dio 和缓存插件
import 'package:dio/dio.dart';
import 'package:dio_http_cache_thmoises/dio_http_cache_thmoises.dart';
void main() async {
Dio dio = Dio();
DioCacheManager dioCacheManager = DioCacheManager(CacheConfig());
dio.interceptors.add(dioCacheManager.interceptor);
}
- 发起带缓存的请求
void fetchData() async {
var response = await dio.get(
'https://jsonplaceholder.typicode.com/posts',
options: buildCacheOptions(
Duration(days: 7), // 缓存有效期为7天
forceRefresh: true, // 是否强制刷新缓存
),
);
print(response.data);
}
缓存配置
CacheConfig
允许你自定义缓存的行为,例如缓存存储路径、最大缓存大小等。
CacheConfig cacheConfig = CacheConfig(
baseUrl: "https://jsonplaceholder.typicode.com",
defaultMaxAge: Duration(days: 7),
maxMemoryCacheCount: 100,
diskCachePath: "path_to_cache_directory",
);
DioCacheManager dioCacheManager = DioCacheManager(cacheConfig);
缓存策略
buildCacheOptions
方法允许你为每个请求指定不同的缓存策略:
maxAge
: 缓存的最大有效期。forceRefresh
: 是否强制刷新缓存(即使缓存未过期)。subKey
: 用于区分同一 URL 下的不同缓存。
var response = await dio.get(
'https://jsonplaceholder.typicode.com/posts/1',
options: buildCacheOptions(
Duration(days: 1),
forceRefresh: false,
subKey: 'post1',
),
);
清除缓存
你可以通过 DioCacheManager
来清除缓存:
// 清除所有缓存
await dioCacheManager.clearAll();
// 清除指定 URL 的缓存
await dioCacheManager.delete('https://jsonplaceholder.typicode.com/posts');