Flutter中如何持久化树对象缓存数据,提升程序运行速度?
在Dart/Flutter中缓存解析后的树对象
嘿,这个场景我太熟悉了!之前处理大体积文档解析的时候也被卡过,Dart里确实没有Python的pickle或者C++直接dump对象那么“粗暴”的方式,但有几个非常实用的方案能搞定这个缓存需求,我给你逐个拆解:
方案1:JSON序列化(最通用易上手)
如果你的树对象是自定义类,咱们可以借助json_serializable包把对象转成JSON字符串存到文件,读取时再反序列化回来。这是最基础的方案,不需要额外复杂的配置。
步骤:
- 先在
pubspec.yaml里加依赖:
dependencies: json_annotation: ^4.8.1 dev_dependencies: build_runner: ^2.4.4 json_serializable: ^6.7.1
- 给你的树节点类加上序列化注解:
import 'package:json_annotation/json_annotation.dart'; part 'tree_node.g.dart'; @JsonSerializable() class TreeNode { final String content; final List<TreeNode> children; TreeNode({required this.content, required this.children}); // 生成的序列化方法 factory TreeNode.fromJson(Map<String, dynamic> json) => _$TreeNodeFromJson(json); Map<String, dynamic> toJson() => _$TreeNodeToJson(this); }
- 运行命令生成序列化代码:
flutter pub run build_runner build
- 最后实现你的缓存逻辑:
import 'dart:convert'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; Future<TreeNode> getTree(String htmlBook) async { // 获取缓存文件路径 final directory = await getApplicationDocumentsDirectory(); final cacheFile = File('${directory.path}/processed_tree.json'); if (await cacheFile.exists()) { // 读取缓存 final jsonString = await cacheFile.readAsString(); final jsonMap = jsonDecode(jsonString) as Map<String, dynamic>; return TreeNode.fromJson(jsonMap); } else { // 解析并缓存 final tree = heavyParsing(htmlBook); final jsonString = jsonEncode(tree.toJson()); await cacheFile.writeAsString(jsonString); return tree; } }
方案2:二进制序列化(更快更省空间)
如果JSON的速度或体积满足不了需求,可以用二进制序列化。Dart自带的dart:convert里有BinaryCodec,或者更推荐用Protobuf(谷歌的二进制序列化协议),性能和压缩比都更优。
简单示例(用Protobuf):
- 定义
.proto文件描述你的树结构:
syntax = "proto3"; message TreeNode { string content = 1; repeated TreeNode children = 2; }
- 生成Dart代码,然后就能直接序列化/反序列化二进制数据,读写到文件的逻辑和JSON类似,只是把JSON换成Protobuf的方法。
方案3:用Hive做对象持久化(最省心高效)
Hive是Flutter里非常流行的轻量级NoSQL数据库,支持直接存储自定义对象,不需要JSON序列化,速度极快,特别适合缓存这种复杂对象。
步骤:
- 加依赖:
dependencies: hive: ^2.2.3 hive_flutter: ^1.1.0 dev_dependencies: hive_generator: ^1.1.5 build_runner: ^2.4.4
- 注册自定义对象的适配器:
import 'package:hive/hive.dart'; part 'tree_node.g.dart'; @HiveType(typeId: 0) class TreeNode { @HiveField(0) final String content; @HiveField(1) final List<TreeNode> children; TreeNode({required this.content, required this.children}); }
- 生成适配器代码:
flutter pub run build_runner build
- 实现缓存逻辑:
import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; Future<TreeNode> getTree(String htmlBook) async { // 初始化Hive await Hive.initFlutter(); Hive.registerAdapter(TreeNodeAdapter()); final box = await Hive.openBox('tree_cache'); final cachedTree = box.get('processed_tree') as TreeNode?; if (cachedTree != null) { return cachedTree; } else { final tree = heavyParsing(htmlBook); await box.put('processed_tree', tree); return tree; } }
最后给个小建议
如果你的树结构不复杂,用JSON序列化足够简单;如果追求极致性能,Hive或者Protobuf是更好的选择——我之前用Hive缓存过类似的大解析对象,速度提升非常明显,从5秒左右直接降到几百毫秒!
内容的提问来源于stack exchange,提问作者Hairy Ass
相关产品推荐
相关产品推荐

