Flutter for OpenHarmony:dio_cache_interceptor 为网络请求添加标准缓存策略(HTTP 缓存拦截器) 深度解析与鸿蒙适配指南
本文介绍了在OpenHarmony项目中集成dio_cache_interceptor插件实现HTTP缓存的方法。该插件基于Flutter流行网络库dio,提供符合HTTP标准的缓存策略,支持多种存储后端和灵活的缓存模式。文章详细讲解了核心功能、OpenHarmony适配要点、集成配置步骤,并通过三个示例演示了基础缓存、强制刷新和持久化缓存的使用场景。最后给出了一个完整的离线新闻列表实战案例,展示
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
前言
在移动应用开发中,网络请求往往是耗电且耗时的。为了提升用户体验(如离线访问、秒开页面)和减少服务器负载,HTTP 缓存机制至关重要。
dio 是 Flutter 最流行的网络库,而 dio_cache_interceptor 是基于它的强大插件,提供了符合 HTTP 标准(RFC 7234)的缓存策略。本文将带你一步步在 OpenHarmony 项目中集成它,打造高性能的网络层。
一、核心特性与适配
1.1 核心功能
- 多存储后端:支持内存 (MemStore)、文件 (FileStore)、数据库 (DbStore/HiveStore) 等。
- 策略灵活:支持
CachePolicy.forceCache,refresh,noCache等多种模式。 - 标准兼容:自动处理
ETag,Last-Modified,Cache-Control等头信息。
1.2 OpenHarmony 适配说明
该库主要依赖 Dart 的 IO 和存储能力。在 OpenHarmony 上:
- MemStore: 直接可用。
- FileStore/DbStore: 需配合
path_provider获取应用沙箱路径。 - HiveStore: 需确保
hive已适配(通常纯 Dart 版没问题)。
本教程推荐使用 MemCacheStore(测试用)或 FileCacheStore(持久化)。
二、集成与配置
2.1 添加依赖
dependencies:
dio: ^5.0.0
dio_cache_interceptor: ^3.5.0
# 鸿蒙适配版本 (示例)
path_provider:
git:
url: https://gitee.com/openharmony-sig/flutter_packages.git
path: packages/path_provider/path_provider
2.2 基础配置
初始化 Dio 并添加拦截器。
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
// import 'package:dio_cache_interceptor_file_store/dio_cache_interceptor_file_store.dart'; // 需额外引入 store 库
// 全局缓存选项配置
final options = CacheOptions(
store: MemCacheStore(), // 内存存储,重启即失
policy: CachePolicy.request, // 默认策略:有缓存读缓存,过期则请求
hitCacheOnErrorExcept: [401, 403], // 遇到特定错误时也尝试返回缓存
maxStale: const Duration(days: 7), // 最大过期时间
priority: CachePriority.normal, // 缓存优先级
cipher: null, // 可选加密
keyBuilder: CacheOptions.defaultCacheKeyBuilder,
allowPostMethod: false, // 默认不缓存 POST
);
final dio = Dio()..interceptors.add(DioCacheInterceptor(options: options));
三、缓存策略详解与示例
3.1 示例一:基础 GET 请求缓存
最简单的用法,利用默认配置发起 GET 请求。
Future<void> fetchUserData() async {
try {
// 第一次请求:从网络获取并缓存
var response = await dio.get('https://api.example.com/user/1');
print('First call: ${response.statusCode}, Source: ${response.extra}');
// 第二次请求(如果未过期):直接返回缓存
response = await dio.get('https://api.example.com/user/1');
print('Second call: ${response.statusCode}, Source: ${response.extra}');
} catch (e) {
print('Failed: $e');
}
}

3.2 示例二:强制刷新与强制缓存
有时我们需要手动控制缓存行为。
// 强制刷新:忽略本地缓存,从网络拉取并更新缓存
dio.get(
'url',
options: options.copyWith(policy: CachePolicy.refresh).toOptions(),
);
// 强制缓存:无论是否过期,只要有缓存就用(常用于离线模式)
dio.get(
'url',
options: options.copyWith(policy: CachePolicy.forceCache).toOptions(),
);

3.3 示例三:持久化缓存(OpenHarmony 适配)
使用文件系统存储缓存,即使 App 重启也能生效。需要 path_provider。
import 'package:path_provider/path_provider.dart';
import 'package:dio_cache_interceptor_file_store/dio_cache_interceptor_file_store.dart';
Future<CacheStore> getFileStore() async {
final dir = await getApplicationDocumentsDirectory();
// 在 OpenHarmony 沙箱目录下创建缓存文件夹
return FileCacheStore('${dir.path}/http_cache');
}

四、完整实战示例:离线新闻列表
本示例展示一个简单的新闻列表页。即使断网,用户也能看到上次加载的数据。
4.1 核心逻辑
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
// 注意:实际项目中通常需要单独引入 store 库,这里假设使用内存或已定义的文件 store
// import 'package:dio_cache_interceptor_store_file/dio_cache_interceptor_store_file.dart';
void main() {
runApp(const MaterialApp(home: NewsPage()));
}
class NewsPage extends StatefulWidget {
const NewsPage({super.key});
State<NewsPage> createState() => _NewsPageState();
}
class _NewsPageState extends State<NewsPage> {
late Dio _dio;
String _content = "暂无数据";
bool _loading = false;
void initState() {
super.initState();
_initDio();
}
void _initDio() {
// 简单起见使用内存存储
final options = CacheOptions(
store: MemCacheStore(),
policy: CachePolicy.forceCache, // 优先读缓存
hitCacheOnErrorExcept: [],
maxStale: const Duration(days: 1),
);
_dio = Dio()..interceptors.add(DioCacheInterceptor(options: options));
}
Future<void> _loadNews({bool forceRefresh = false}) async {
setState(() {
_loading = true;
_content = "加载中...";
});
try {
final cacheOptions = CacheOptions(
store: MemCacheStore(), // 注意:这里创建新的 store 实例仅作演示,实际应复用
policy: forceRefresh ? CachePolicy.refresh : CachePolicy.forceCache,
);
// 模拟请求一个公共 API
final response = await _dio.get(
'https://jsonplaceholder.typicode.com/posts/1',
options: forceRefresh
? Options(extra: cacheOptions.toExtra()) // 覆盖默认策略
: null,
);
final isFromCache = response.extra[CacheResponse.fromNetwork] == false;
setState(() {
_content = "标题: ${response.data['title']}\n"
"来源: ${isFromCache ? '📦 本地缓存' : '🌐 网络请求'}";
});
} catch (e) {
setState(() => _content = "错误: $e");
} finally {
setState(() => _loading = false);
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('离线新闻 Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.all(16),
color: Colors.grey[200],
child: Text(
_content,
style: const TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton.icon(
icon: const Icon(Icons.download),
label: const Text('加载 (优先缓存)'),
onPressed: () => _loadNews(forceRefresh: false),
),
const SizedBox(width: 20),
ElevatedButton.icon(
icon: const Icon(Icons.refresh),
label: const Text('刷新 (强制网络)'),
onPressed: () => _loadNews(forceRefresh: true),
),
],
),
],
),
),
);
}
}

五、总结
dio_cache_interceptor 是 Flutter 生态中最成熟的 HTTP 缓存方案之一。配合 OpenHarmony 的文件系统,它能极大地提升应用的响应速度和离线可用性。
最佳实践:
- 策略选择:对于实时性要求高的数据(如股价),使用
refresh;对于内容类(如文章),使用cacheFirst或forceCache。 - 清理过期缓存:虽然库会自动管理,但建议在设置页提供“清除缓存”的功能,通过
cacheStore.clean()释放空间。 - OpenHarmony 路径:确保持久化存储路径正确,避免权限问题。
更多推荐


所有评论(0)