Flutter网络请求与缓存插件dio_http_cache_thmoises的使用

Flutter网络请求与缓存插件dio_http_cache_thmoises的使用

dio-http-cache

Pub

中文介绍

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

默认情况下,查询参数(dataqueryParameters)作为子键。必要时可以指定子键。

buildCacheOptions(Duration(days: 7), subKey: "page=1")
c. maxAge

设置缓存的有效期。如果值为 null 或未设置,则会尝试从响应头中获取 maxAgemaxStale

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. encryptdecrypt

这两个方法必须一起使用来加密磁盘上的缓存数据,也可以在这里压缩数据。

CacheConfig(
  encrypt: encryptFunction,
  decrypt: decryptFunction,
)
c. defaultMaxAgedefaultMaxStale

默认值分别为 Duration(days: 7)

CacheConfig(defaultMaxAge: Duration(days: 3), defaultMaxStale: Duration(days: 10))
d. databasePathdatabaseName

数据库的路径和名称。

CacheConfig(databasePath: "/path/to/db", databaseName: "my_cache.db")
e. skipMemoryCacheskipDiskCache

默认值均为 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 {
  // 数据来自网络
}

示例:maxAgemaxStale

_dio.post(
  "https://www.example.com",
  data: {'k': "keyword"},
  options: buildCacheOptions(
    Duration(days: 3), 
    maxStale: Duration(days: 7), 
  )
)
  • 0 ~ 3 天:直接从缓存中返回数据(与网络无关)。
  • 3 ~ 7 天:
    1. 先从网络获取数据。
    2. 如果成功,刷新缓存。
    3. 如果失败或无网络,尝试从缓存中读取。
  • 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

1 回复

更多关于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 来安装依赖。

基本用法

  1. 初始化 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);
}
  1. 发起带缓存的请求
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');
回到顶部