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

发布于 1周前 作者 bupafengyu 来自 Flutter

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

简介

dio_cache_interceptor 是一个为 Dio HTTP 请求提供缓存功能的拦截器。它支持多种存储方式,遵循HTTP缓存指令,并允许开发者自定义缓存策略。

pub package codecov

HTTP 缓存指令支持

类别 指令
Cache triggers ETag, Last-Modified, Date
Cache freshness Age, Date, Expires, max-age (Cache-Control), max-stale (Cache-Control), min-fresh (Cache-Control), must-revalidate, Request date (added by interceptor), Response date (added by interceptor)
Cache commutators no-cache (Cache-Control), no-store (Cache-Control request & response)

支持的存储类型

  • BackupCacheStore: 主备组合存储
  • DbCacheStore: 使用Drift数据库缓存 获取
  • FileCacheStore: 文件系统缓存(Web平台不支持)获取
  • HiveCacheStore: 使用Hive包缓存(支持所有平台)获取
  • IsarCacheStore: 使用Isar包缓存(支持所有平台)获取
  • ObjectBoxCacheStore: 使用ObjectBox包缓存(不支持Web)获取
  • SembastCacheStore: 使用Sembast包缓存 获取
  • MemCacheStore: 内存缓存,默认采用LRU策略

使用方法

1. 安装依赖

pubspec.yaml 中添加依赖:

dependencies:
  dio: ^5.0.0
  dio_cache_interceptor: ^2.0.0

2. 配置全局选项

import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';

final options = const CacheOptions(
  store: MemCacheStore(),
  policy: CachePolicy.request,
  hitCacheOnErrorExcept: [401, 403],
  maxStale: Duration(days: 7),
  priority: CachePriority.normal,
);

3. 添加拦截器

final dio = Dio()
  ..interceptors.add(DioCacheInterceptor(options: options));

4. 发起请求

// 使用默认缓存策略
var response = await dio.get('https://www.foo.com');

// 使用刷新策略
response = await dio.get(
  'https://www.foo.com',
  options: options.copyWith(policy: CachePolicy.refresh).toOptions(),
);

5. 示例代码

下面是一个完整的示例应用,展示了如何集成 dio_cache_interceptor 并实现不同场景下的缓存逻辑:

import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late CacheStore cacheStore;
  late CacheOptions cacheOptions;
  late Dio dio;

  @override
  void initState() {
    super.initState();
    cacheStore = MemCacheStore(maxSize: 10485760, maxEntrySize: 1048576);
    cacheOptions = CacheOptions(
      store: cacheStore,
      hitCacheOnErrorExcept: [],
    );

    dio = Dio()
      ..interceptors.add(DioCacheInterceptor(options: cacheOptions));
  }

  @override
  void dispose() async {
    dio.close();
    await cacheStore.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dio Cache Example',
      home: Scaffold(
        appBar: AppBar(title: Text('Dio Cache Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: () async {
                  final response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
                  print(response.data);
                },
                child: Text('Fetch Data'),
              ),
              ElevatedButton(
                onPressed: () async {
                  final response = await dio.get(
                    'https://jsonplaceholder.typicode.com/posts/1',
                    options: Options(extra: {'cache': true}),
                  );
                  print(response.data);
                },
                child: Text('Fetch Cached Data'),
              ),
              ElevatedButton(
                onPressed: () async {
                  final response = await dio.get(
                    'https://jsonplaceholder.typicode.com/posts/1',
                    options: options.copyWith(policy: CachePolicy.refresh).toOptions(),
                  );
                  print(response.data);
                },
                child: Text('Refresh Cache'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

此示例中,我们创建了一个简单的Flutter应用,演示了如何使用 dio_cache_interceptor 来处理不同的缓存策略。用户可以通过点击按钮来触发不同类型的HTTP请求,并观察控制台输出的结果。

其他特性

缓存策略

CachePolicy 枚举定义了五种主要的缓存策略:

  • forceCache: 强制使用缓存,即使服务器没有配置缓存。
  • refreshForceCache: 刷新并强制使用缓存。
  • noCache: 不使用缓存。
  • refresh: 默认策略,尝试从服务器获取最新数据,但会遵守服务器的缓存指令。
  • request: 尝试使用缓存,如果不存在则从服务器获取。

加密支持

可以使用 CacheCipher 接口来自定义加密算法,对缓存的数据进行加密和解密。

更多详细信息请参考官方文档:dio_cache_interceptor 文档

希望这个指南能帮助你更好地理解和使用 dio_cache_interceptor 插件!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter网络请求缓存插件dio_cache_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络请求缓存插件dio_cache_interceptor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用dio_cache_interceptor插件来进行网络请求缓存的示例代码。dio_cache_interceptor是一个基于dio库的拦截器,用于缓存HTTP请求和响应。

首先,确保你已经在pubspec.yaml文件中添加了必要的依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.0  # 确保版本兼容
  dio_cache_interceptor: ^3.0.0  # 确保版本兼容

然后运行flutter pub get来安装这些依赖。

接下来,你可以在你的Flutter项目中配置和使用dio_cache_interceptor。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dio Cache Interceptor Example'),
        ),
        body: Center(
          child: NetworkRequestWidget(),
        ),
      ),
    );
  }
}

class NetworkRequestWidget extends StatefulWidget {
  @override
  _NetworkRequestWidgetState createState() => _NetworkRequestWidgetState();
}

class _NetworkRequestWidgetState extends State<NetworkRequestWidget> {
  String responseData = '';

  @override
  void initState() {
    super.initState();
    _setupDio();
  }

  void _setupDio() async {
    // 创建Dio实例
    var dio = Dio();

    // 配置缓存拦截器
    var cacheConfig = CacheConfig(
      basePath: 'path_to_cache_directory', // 指定缓存存储的目录
      defaultExpiration: const Duration(days: 7), // 设置默认缓存过期时间
      enableLog: true, // 是否打印缓存日志
    );
    var cacheInterceptor = DioCacheInterceptor(config: cacheConfig);

    // 添加拦截器到dio实例
    dio.interceptors.add(cacheInterceptor);

    // 发起网络请求
    try {
      var response = await dio.get('https://jsonplaceholder.typicode.com/posts/1');
      setState(() {
        responseData = response.data.toString();
      });
    } catch (e) {
      print('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Response Data:'),
        Text(responseData),
      ],
    );
  }
}

注意事项:

  1. 缓存目录

    • basePath: 'path_to_cache_directory' 替换为你希望存储缓存数据的目录路径。在实际应用中,你可能需要使用平台特定的路径,比如getApplicationDocumentsDirectory()来获取iOS和Android上的合适路径。
  2. 缓存策略

    • 你可以通过CacheConfig来配置不同的缓存策略,比如设置不同的过期时间、是否启用日志等。
  3. 依赖版本

    • 确保你使用的diodio_cache_interceptor版本是兼容的。上面的版本号只是一个示例,你可能需要查看最新的pub.dev页面来获取最新版本。
  4. 错误处理

    • 在实际应用中,你可能需要更复杂的错误处理逻辑,比如处理网络错误、解析错误等。

这个示例展示了如何配置dio实例并添加dio_cache_interceptor来缓存网络请求。你可以根据实际需求进一步扩展和修改这个示例。

回到顶部