Flutter for OpenHarmony网络请求与数据持久化完全指南
### 文章目录
- [Flutter for OpenHarmony网络请求与数据持久化完全指南](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [@[toc]](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [前言](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [一、网络请求基础封装](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [1.1 HTTP客户端封装](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [1.2 API响应封装](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [二、网络请求异常处理](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [2.1 异常类型定义](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [2.2 异常处理器](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [三、数据持久化方案](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [3.1 Token管理](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [3.2 缓存管理](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [四、完整的API服务](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [4.1 API基础服务](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [总结](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [核心要点回顾](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
- [最佳实践建议](#文章目录 Flutter for OpenHarmony网络请求与数据持久化完全指南 @[toc] 前言 一、网络请求基础封装 1.1 HTTP客户端封装 1.2 API响应封装 二、网络请求异常处理 2.1 异常类型定义 2.2 异常处理器 三、数据持久化方案 3.1 Token管理 3.2 缓存管理 四、完整的API服务 4.1 API基础服务 总结 核心要点回顾 最佳实践建议)
前言

网络请求和数据持久化是现代应用开发的核心。无论是调用REST API、处理认证token,还是缓存离线数据,都是必备技能。
Flutter for OpenHarmony 提供了丰富的网络请求库,但在实际开发中,很多开发者会遇到以下问题:
- HTTP请求如何封装复用?
- Token过期自动刷新如何实现?
- 网络异常如何优雅处理?
- 离线缓存如何设计?
- 如何提升网络请求性能?
这篇文章我将系统性地讲解Flutter for OpenHarmony中的网络请求与数据持久化方案。
本文亮点:
- 完整的网络请求封装实现
- Token自动刷新机制
- 统一异常处理方案
- 离线缓存设计
- 网络请求性能优化
一、网络请求基础封装
1.1 HTTP客户端封装

添加依赖:
yaml
dependencies:
dio: ^5.3.4
pretty_dio_logger: ^1.3.1
实现HTTP客户端:
dart
import 'package:dio/dio.dart';
/// 网络请求配置
class NetworkConfig {
static const String baseUrl = 'https://api.example.com';
static const Duration connectTimeout = Duration(seconds: 30);
static const Duration receiveTimeout = Duration(seconds: 30);
static const Duration sendTimeout = Duration(seconds: 30);
}
/// HTTP客户端封装
class HttpClient {
static final HttpClient _instance = HttpClient._internal();
factory HttpClient() => _instance;
HttpClient._internal() {
_dio = Dio(
BaseOptions(
baseUrl: NetworkConfig.baseUrl,
connectTimeout: NetworkConfig.connectTimeout,
receiveTimeout: NetworkConfig.receiveTimeout,
sendTimeout: NetworkConfig.sendTimeout,
headers: {
'Content-Type': 'application/json',
},
),
);
_setupInterceptors();
}
late final Dio _dio;
/// 获取Dio实例
Dio get dio => _dio;
/// 设置拦截器
void _setupInterceptors() {
_dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
// 请求拦截
debugPrint('请求: ${options.method} ${options.uri}');
// 添加Token
final token = TokenManager().getToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
return handler.next(options);
},
onResponse: (response, handler) {
// 响应拦截
debugPrint('响应: ${response.statusCode}');
return handler.next(response);
},
onError: (error, handler) {
// 错误拦截
debugPrint('错误: ${error.message}');
// 处理401错误(Token过期)
if (error.response?.statusCode == 401) {
_handleTokenExpired();
}
return handler.next(error);
},
),
);
}
/// 处理Token过期
Future<void> _handleTokenExpired() async {
// 尝试刷新Token
final success = await TokenManager().refreshToken();
if (!success) {
// 刷新失败,跳转到登录页
// Navigator.pushReplacementNamed(context, '/login');
}
}
}
1.2 API响应封装
dart
/// API响应基础类
class ApiResponse<T> {
final int code;
final String message;
final T? data;
final bool success;
ApiResponse({
required this.code,
required this.message,
this.data,
required this.success,
});
factory ApiResponse.success(T data) {
return ApiResponse(
code: 200,
message: '成功',
data: data,
success: true,
);
}
factory ApiResponse.error(int code, String message) {
return ApiResponse(
code: code,
message: message,
success: false,
);
}
factory ApiResponse.fromJson(Map<String, dynamic> json) {
return ApiResponse(
code: json['code'] as int,
message: json['message'] as String,
data: json['data'],
success: json['code'] == 200,
);
}
}
/// 分页响应
class PagedResponse<T> {
final List<T> items;
final int page;
final int pageSize;
final int total;
PagedResponse({
required this.items,
required this.page,
required this.pageSize,
required this.total,
});
factory PagedResponse.fromJson(
Map<String, dynamic> json,
T Function(Map<String, dynamic>) fromJsonT,
) {
final itemsList = json['items'] as List<dynamic>;
return PagedResponse(
items: itemsList.map((e) => fromJsonT(e as Map<String, dynamic>)).toList(),
page: json['page'] as int,
pageSize: json['pageSize'] as int,
total: json['total'] as int,
);
}
bool get hasMore => (page * pageSize) < total;
}
二、网络请求异常处理

2.1 异常类型定义
dart
/// 网络异常基类
abstract class NetworkException implements Exception {
final String message;
final int? code;
NetworkException(this.message, [this.code]);
@override
String toString() => message;
}
/// 请求超时异常
class RequestTimeoutException extends NetworkException {
RequestTimeoutException([String message = '请求超时'])
: super(message, 408);
}
/// 网络连接异常
class NetworkConnectException extends NetworkException {
NetworkConnectException([String message = '网络连接失败'])
: super(message, -1);
}
/// 服务器异常
class ServerException extends NetworkException {
ServerException(String message, [int? code])
: super(message, code ?? 500);
}
/// 业务异常
class BusinessException extends NetworkException {
BusinessException(String message, [int? code])
: super(message, code ?? 400);
}
/// 未授权异常
class UnauthorizedException extends NetworkException {
UnauthorizedException([String message = '未授权'])
: super(message, 401);
}
/// Token过期异常
class TokenExpiredException extends NetworkException {
TokenExpiredException([String message = 'Token已过期'])
: super(message, 401);
}
2.2 异常处理器
dart
/// 异常处理器
class ExceptionHandler {
static String handleError(dynamic error) {
if (error is DioException) {
return _handleDioError(error);
} else if (error is NetworkException) {
return error.message;
} else {
return '未知错误: $error';
}
}
static String _handleDioError(DioException error) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
return '请求超时,请检查网络连接';
case DioExceptionType.connectionError:
return '网络连接失败,请检查网络';
case DioExceptionType.badResponse:
final statusCode = error.response?.statusCode;
switch (statusCode) {
case 400:
return '请求参数错误';
case 401:
return '未授权,请重新登录';
case 403:
return '无权限访问';
case 404:
return '请求的资源不存在';
case 500:
return '服务器内部错误';
default:
return '服务器错误($statusCode)';
}
case DioExceptionType.cancel:
return '请求已取消';
case DioExceptionType.unknown:
return '网络异常,请稍后重试';
default:
return '网络请求失败';
}
}
static NetworkException parseException(dynamic error) {
if (error is NetworkException) {
return error;
}
if (error is DioException) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
return RequestTimeoutException();
case DioExceptionType.connectionError:
return NetworkConnectException();
case DioExceptionType.badResponse:
final statusCode = error.response?.statusCode;
if (statusCode == 401) {
return TokenExpiredException();
} else if (statusCode == 403) {
return UnauthorizedException();
} else if (statusCode != null && statusCode! >= 500) {
return ServerException('服务器错误', statusCode);
} else {
return BusinessException('请求错误', statusCode);
}
default:
return NetworkConnectException();
}
}
return NetworkConnectException('未知错误');
}
}
三、数据持久化方案

3.1 Token管理
dart
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
/// Token管理器
class TokenManager {
static final TokenManager _instance = TokenManager._internal();
factory TokenManager() => _instance;
TokenManager._internal();
final String _tokenKey = 'auth_token';
final String _refreshTokenKey = 'refresh_token';
/// 保存Token
Future<void> saveToken(String token) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_tokenKey, token);
}
/// 获取Token
Future<String?> getToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(_tokenKey);
}
/// 清除Token
Future<void> clearToken() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_tokenKey);
await prefs.remove(_refreshTokenKey);
}
/// 检查Token是否有效
Future<bool> isTokenValid() async {
final token = await getToken();
if (token == null) return false;
try {
final parts = token.split('.');
if (parts.length != 3) return false;
final payload = jsonDecode(
utf8.decode(base64Url.decode(parts[1])),
) as Map<String, dynamic>;
final exp = payload['exp'] as int?;
if (exp == null) return false;
return DateTime.now().millisecondsSinceEpoch ~/ 1000 < exp;
} catch (e) {
return false;
}
}
/// 刷新Token
Future<bool> refreshToken() async {
try {
final prefs = await SharedPreferences.getInstance();
final refreshToken = prefs.getString(_refreshTokenKey);
if (refreshToken == null) {
return false;
}
final response = await HttpClient().dio.post(
'/auth/refresh',
data: {'refresh_token': refreshToken},
);
if (response.statusCode == 200) {
final newToken = response.data['data']['access_token'] as String;
await saveToken(newToken);
return true;
}
return false;
} catch (e) {
return false;
}
}
}
3.2 缓存管理
dart
/// 缓存管理器
class CacheManager {
static final CacheManager _instance = CacheManager._internal();
factory CacheManager() => _instance;
CacheManager._internal();
final String _cachePrefix = 'cache_';
final String _cacheTimePrefix = 'cache_time_';
/// 缓存数据
Future<void> set(String key, dynamic data) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_cachePrefix + key, jsonEncode(data));
await prefs.setString(
_cacheTimePrefix + key,
DateTime.now().millisecondsSinceEpoch.toString(),
);
}
/// 获取缓存数据
Future<T?> get<T>(String key) async {
final prefs = await SharedPreferences.getInstance();
final data = prefs.getString(_cachePrefix + key);
if (data == null) return null;
return jsonDecode(data) as T;
}
/// 获取缓存时间
Future<DateTime?> getCacheTime(String key) async {
final prefs = await SharedPreferences.getInstance();
final time = prefs.getString(_cacheTimePrefix + key);
if (time == null) return null;
return DateTime.fromMillisecondsSinceEpoch(int.parse(time));
}
/// 检查缓存是否过期
Future<bool> isExpired(String key, Duration duration) async {
final cacheTime = await getCacheTime(key);
if (cacheTime == null) return true;
final now = DateTime.now();
return now.difference(cacheTime) > duration;
}
/// 清除缓存
Future<void> remove(String key) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_cachePrefix + key);
await prefs.remove(_cacheTimePrefix + key);
}
/// 清除所有缓存
Future<void> clear() async {
final prefs = await SharedPreferences.getInstance();
final keys = prefs.getKeys();
for (final key in keys) {
if (key.startsWith(_cachePrefix) || key.startsWith(_cacheTimePrefix)) {
await prefs.remove(key);
}
}
}
}
四、完整的API服务
4.1 API基础服务
dart
/// API基础服务
class ApiService {
final HttpClient _httpClient = HttpClient();
/// GET请求
Future<ApiResponse<T>> get<T>(
String path, {
Map<String, dynamic>? queryParameters,
bool useCache = false,
Duration cacheDuration = const Duration(minutes: 5),
}) async {
try {
// 检查缓存
if (useCache) {
final cacheKey = path + (queryParameters?.toString() ?? '');
final isExpired = await CacheManager().isExpired(
cacheKey,
cacheDuration,
);
if (!isExpired) {
final cachedData = await CacheManager().get<T>(cacheKey);
if (cachedData != null) {
return ApiResponse.success(cachedData);
}
}
}
// 发起请求
final response = await _httpClient.dio.get(
path,
queryParameters: queryParameters,
);
final apiResponse = ApiResponse<T>.fromJson(response.data);
// 缓存数据
if (useCache && apiResponse.success) {
final cacheKey = path + (queryParameters?.toString() ?? '');
await CacheManager().set(cacheKey, response.data);
}
return apiResponse;
} catch (e) {
final exception = ExceptionHandler.parseException(e);
throw exception;
}
}
/// POST请求
Future<ApiResponse<T>> post<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
}) async {
try {
final response = await _httpClient.dio.post(
path,
data: data,
queryParameters: queryParameters,
);
return ApiResponse<T>.fromJson(response.data);
} catch (e) {
final exception = ExceptionHandler.parseException(e);
throw exception;
}
}
/// PUT请求
Future<ApiResponse<T>> put<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
}) async {
try {
final response = await _httpClient.dio.put(
path,
data: data,
queryParameters: queryParameters,
);
return ApiResponse<T>.fromJson(response.data);
} catch (e) {
final exception = ExceptionHandler.parseException(e);
throw exception;
}
}
/// DELETE请求
Future<ApiResponse<T>> delete<T>(
String path, {
dynamic data,
Map<String, dynamic>? queryParameters,
}) async {
try {
final response = await _httpClient.dio.delete(
path,
data: data,
queryParameters: queryParameters,
);
return ApiResponse<T>.fromJson(response.data);
} catch (e) {
final exception = ExceptionHandler.parseException(e);
throw exception;
}
}
/// 文件上传
Future<ApiResponse<String>> uploadFile(
String path,
String filePath, {
String? fieldName,
ProgressCallback? onSendProgress,
}) async {
try {
final file = await MultipartFile.fromFile(filePath);
final formData = FormData.fromMap({
fieldName ?? 'file': file,
});
final response = await _httpClient.dio.post(
path,
data: formData,
onSendProgress: onSendProgress,
);
return ApiResponse<String>.fromJson(response.data);
} catch (e) {
final exception = ExceptionHandler.parseException(e);
throw exception;
}
}
}
总结
本文系统性地讲解了Flutter for OpenHarmony中的网络请求与数据持久化,从基础封装到高级应用。
核心要点回顾
| 技术点 | 关键内容 | 注意事项 |
|---|---|---|
| HTTP封装 | Dio封装、拦截器 | 统一管理请求 |
| 异常处理 | 自定义异常类型 | 友好提示用户 |
| Token管理 | 存储、刷新、验证 | 自动处理过期 |
| 缓存策略 | 本地缓存、过期时间 | 减少网络请求 |
最佳实践建议
- 统一封装HTTP客户端
- 实现Token自动刷新
- 合理使用缓存减少请求
- 统一异常处理机制
- 做好请求日志记录
- 注意网络状态监听
相关资源:
欢迎加入开源鸿蒙跨平台社区 : 开源鸿蒙跨平台开发者社区
如果这篇文章对你有帮助,请点赞、收藏、分享,让更多开发者看到!
写于2025年 | Flutter for OpenHarmony系列教程