当前位置: 首页 > news >正文

【Flutter x 鸿蒙】第六篇:状态管理、数据持久化与分布式数据 - 青青子衿-

【Flutter x 鸿蒙】第六篇:状态管理、数据持久化与分布式数据

在掌握了Flutter与鸿蒙的导航和多设备适配后,今天我们深入探讨状态管理数据持久化鸿蒙分布式数据这三个核心主题。这些技术是构建复杂、高性能Flutter应用的基础,也是充分利用鸿蒙分布式特性的关键。

一、Flutter状态管理方案选型

1.1 状态管理方案对比

在Flutter开发中,选择合适的方案至关重要。以下是主流方案的对比:

方案 适用场景 学习曲线 性能表现 代码量
Provider 中小型应用,简单状态共享 优秀
Riverpod 中大型应用,复杂状态管理 优秀 中等
Bloc/Cubit 大型应用,复杂业务逻辑 中高 优秀 较多
GetX 快速开发,全功能框架 优秀
MobX 响应式状态管理 优秀 中等

1.2 Provider实战:计数器应用

Provider是Flutter官方推荐的状态管理方案,简单易用:

// lib/models/counter_model.dart
import 'package:flutter/foundation.dart';class CounterModel with ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners();}void decrement() {_count--;notifyListeners();}
}
// lib/pages/counter_page.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/counter_model.dart';class CounterPage extends StatelessWidget {const CounterPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('计数器')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [const Text('当前计数:'),Consumer<CounterModel>(builder: (context, counter, child) {return Text('${counter.count}',style: Theme.of(context).textTheme.headlineMedium,);},),],),),floatingActionButton: Column(mainAxisAlignment: MainAxisAlignment.end,children: [FloatingActionButton(onPressed: () => context.read<CounterModel>().increment(),child: const Icon(Icons.add),),const SizedBox(height: 8),FloatingActionButton(onPressed: () => context.read<CounterModel>().decrement(),child: const Icon(Icons.remove),),],),);}
}

1.3 Riverpod实战:用户信息管理

Riverpod是Provider的升级版,更加强大和灵活:

// lib/providers/user_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';final userProvider = StateNotifierProvider<UserNotifier, UserState>((ref) {return UserNotifier();
});class UserState {final String? name;final String? email;final bool isLoading;UserState({this.name,this.email,this.isLoading = false,});UserState copyWith({String? name,String? email,bool? isLoading,}) {return UserState(name: name ?? this.name,email: email ?? this.email,isLoading: isLoading ?? this.isLoading,);}
}class UserNotifier extends StateNotifier<UserState> {UserNotifier() : super(UserState());Future<void> loadUser() async {state = state.copyWith(isLoading: true);// 模拟网络请求await Future.delayed(const Duration(seconds: 1));state = state.copyWith(name: '张三',email: 'zhangsan@example.com',isLoading: false,);}void updateName(String name) {state = state.copyWith(name: name);}void clearUser() {state = UserState();}
}

二、数据持久化方案

2.1 SharedPreferences:简单键值存储

// lib/services/local_storage_service.dart
import 'package:shared_preferences/shared_preferences.dart';class LocalStorageService {static late SharedPreferences _prefs;static Future<void> init() async {_prefs = await SharedPreferences.getInstance();}// 保存数据static Future<bool> saveString(String key, String value) {return _prefs.setString(key, value);}static Future<bool> saveInt(String key, int value) {return _prefs.setInt(key, value);}static Future<bool> saveBool(String key, bool value) {return _prefs.setBool(key, value);}// 读取数据static String getString(String key, [String defaultValue = '']) {return _prefs.getString(key) ?? defaultValue;}static int getInt(String key, [int defaultValue = 0]) {return _prefs.getInt(key) ?? defaultValue;}static bool getBool(String key, [bool defaultValue = false]) {return _prefs.getBool(key) ?? defaultValue;}// 删除数据static Future<bool> remove(String key) {return _prefs.remove(key);}static Future<bool> clear() {return _prefs.clear();}
}

2.2 Hive:高性能NoSQL数据库

Hive是轻量级、高性能的键值数据库:

# pubspec.yaml
dependencies:hive: ^2.2.3hive_flutter: ^1.1.0path_provider: ^2.0.15
// lib/services/hive_service.dart
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';class HiveService {static const String userBox = 'user_box';static const String settingsBox = 'settings_box';static Future<void> init() async {final appDocumentDir = await getApplicationDocumentsDirectory();Hive.init(appDocumentDir.path);// 注册适配器(如果需要存储自定义对象)// Hive.registerAdapter(UserAdapter());await Hive.openBox(userBox);await Hive.openBox(settingsBox);}// 保存数据static Future<void> saveUserData(String key, dynamic value) async {final box = Hive.box(userBox);await box.put(key, value);}// 读取数据static dynamic getUserData(String key) {final box = Hive.box(userBox);return box.get(key);}// 删除数据static Future<void> deleteUserData(String key) async {final box = Hive.box(userBox);await box.delete(key);}// 清空数据static Future<void> clearUserData() async {final box = Hive.box(userBox);await box.clear();}
}

2.3 SQLite:关系型数据库

对于复杂的数据结构,SQLite是更好的选择:

# pubspec.yaml
dependencies:sqflite: ^2.3.0path: ^1.8.3
// lib/services/database_service.dart
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';class DatabaseService {static Database? _database;static Future<Database> get database async {if (_database != null) return _database!;_database = await _initDatabase();return _database!;}static Future<Database> _initDatabase() async {final databasePath = await getDatabasesPath();final path = join(databasePath, 'app_database.db');return openDatabase(path,version: 1,onCreate: (db, version) async {await db.execute('''CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,email TEXT NOT NULL,created_at INTEGER NOT NULL)''');await db.execute('''CREATE TABLE settings(id INTEGER PRIMARY KEY AUTOINCREMENT,key TEXT NOT NULL,value TEXT NOT NULL,created_at INTEGER NOT NULL)''');},);}// 插入用户static Future<int> insertUser(Map<String, dynamic> user) async {final db = await database;return db.insert('users', user);}// 查询用户static Future<List<Map<String, dynamic>>> getUsers() async {final db = await database;return db.query('users');}// 更新用户static Future<int> updateUser(int id, Map<String, dynamic> user) async {final db = await database;return db.update('users', user, where: 'id = ?', whereArgs: [id]);}// 删除用户static Future<int> deleteUser(int id) async {final db = await database;return db.delete('users', where: 'id = ?', whereArgs: [id]);}
}

三、鸿蒙分布式数据同步

3.1 分布式数据管理原理

鸿蒙的分布式数据管理(Distributed Data Management, DDM)允许应用在不同设备间同步数据,实现无缝的跨设备体验。

3.2 分布式键值存储

// lib/services/distributed_kv_service.dart
import 'package:flutter/services.dart';class DistributedKVService {static const MethodChannel _channel = MethodChannel('com.example/distributed_kv');// 保存数据到分布式存储static Future<bool> save(String key, String value) async {try {final result = await _channel.invokeMethod('save', {'key': key,'value': value,});return result == true;} catch (e) {return false;}}// 从分布式存储读取数据static Future<String?> get(String key) async {try {final result = await _channel.invokeMethod('get', {'key': key});return result as String?;} catch (e) {return null;}}// 删除分布式存储中的数据static Future<bool> delete(String key) async {try {final result = await _channel.invokeMethod('delete', {'key': key});return result == true;} catch (e) {return false;}}// 监听数据变化static Stream<String> get dataChangeStream {return _channel.receiveBroadcastStream().map((event) {return event.toString();});}
}

3.3 鸿蒙端分布式KV实现

// ohos/entry/src/main/ets/services/DistributedKVService.ts
import common from '@ohos.app.ability.common';
import distributed from '@ohos.distributed';
import { BusinessError } from '@ohos.base';export class DistributedKVService {private context: common.UIAbilityContext;private channel: any;private kvManager: any;private kvStore: any;private eventSink: any;constructor(context: common.UIAbilityContext) {this.context = context;this.initChannel();this.initKVStore();}private initChannel() {this.channel = new MethodChannel(this.context,'com.example/distributed_kv',StandardMethodCodec.INSTANCE);this.channel.setMethodCallHandler(this.handleMethodCall.bind(this));// EventChannel用于数据变化监听const eventChannel = new EventChannel(this.context,'com.example/distributed_kv',StandardMessageCodec.INSTANCE);eventChannel.setStreamHandler({onListen: (args: any, events: any) => {this.eventSink = events;},onCancel: (args: any) => {this.eventSink = undefined;}});}private async initKVStore() {try {// 创建KVManagerthis.kvManager = distributed.createKVManager({context: this.context,bundleName: 'com.example.app'});// 创建KVStorethis.kvStore = await this.kvManager.getKVStore('app_data', {createIfMissing: true});// 监听数据变化this.kvStore.on('dataChange', (data: any) => {if (this.eventSink) {this.eventSink.success(`数据变化: ${JSON.stringify(data)}`);}});} catch (error) {console.error('初始化KVStore失败:', error);}}private async handleMethodCall(call: any, result: any) {switch (call.method) {case 'save':await this.saveData(call.arguments, result);break;case 'get':await this.getData(call.arguments, result);break;case 'delete':await this.deleteData(call.arguments, result);break;default:result.notImplemented();}}private async saveData(args: any, result: any) {try {const key = args.key;const value = args.value;await this.kvStore.put(key, value);result.success(true);} catch (error) {result.error('保存数据失败', error.message);}}private async getData(args: any, result: any) {try {const key = args.key;const value = await this.kvStore.get(key);result.success(value);} catch (error) {result.error('获取数据失败', error.message);}}private async deleteData(args: any, result: any) {try {const key = args.key;await this.kvStore.delete(key);result.success(true);} catch (error) {result.error('删除数据失败', error.message);}}
}

3.4 分布式对象存储

对于复杂对象,可以使用分布式对象存储:

// lib/services/distributed_object_service.dart
import 'package:flutter/services.dart';
import 'dart:convert';class DistributedObjectService {static const MethodChannel _channel = MethodChannel('com.example/distributed_object');// 保存对象static Future<bool> saveObject(String key, Map<String, dynamic> object) async {try {final result = await _channel.invokeMethod('saveObject', {'key': key,'value': json.encode(object),});return result == true;} catch (e) {return false;}}// 获取对象static Future<Map<String, dynamic>?> getObject(String key) async {try {final result = await _channel.invokeMethod('getObject', {'key': key});if (result != null) {return json.decode(result as String);}return null;} catch (e) {return null;}}// 监听对象变化static Stream<Map<String, dynamic>> get objectChangeStream {return _channel.receiveBroadcastStream().map((event) {return json.decode(event as String);});}
}

四、状态管理最佳实践

4.1 状态分层架构

将状态按照作用域进行分层管理:

// 应用级状态
final appConfigProvider = StateNotifierProvider<AppConfigNotifier, AppConfig>((ref) {return AppConfigNotifier();
});// 页面级状态
final homePageProvider = StateNotifierProvider<HomePageNotifier, HomePageState>((ref) {return HomePageNotifier();
});// 组件级状态
final counterProvider = StateProvider<int>((ref) => 0);

4.2 状态持久化策略

结合Riverpod和Hive实现状态持久化:

// lib/providers/persistent_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';final persistentCounterProvider = StateNotifierProvider<PersistentCounterNotifier, int>((ref) {return PersistentCounterNotifier();
});class PersistentCounterNotifier extends StateNotifier<int> {PersistentCounterNotifier() : super(0) {_loadFromStorage();}Future<void> _loadFromStorage() async {final value = HiveService.getUserData('counter') ?? 0;state = value;}void increment() {state++;_saveToStorage();}void decrement() {state--;_saveToStorage();}Future<void> _saveToStorage() async {await HiveService.saveUserData('counter', state);}
}

4.3 状态恢复机制

在应用启动时恢复状态:

// lib/main.dart
void main() async {WidgetsFlutterBinding.ensureInitialized();// 初始化数据存储await HiveService.init();// 恢复应用状态final savedCounter = HiveService.getUserData('counter') ?? 0;runApp(ProviderScope(overrides: [persistentCounterProvider.overrideWithValue(PersistentCounterNotifier()..state = savedCounter,),],child: MyApp(),));
}

五、实战案例:跨设备待办事项应用

让我们实现一个完整的跨设备待办事项应用,展示状态管理和分布式数据的实际应用:

// lib/models/todo_model.dart
class Todo {final String id;final String title;final bool completed;final DateTime createdAt;Todo({required this.id,required this.title,this.completed = false,required this.createdAt,});Todo copyWith({String? id,String? title,bool? completed,DateTime? createdAt,}) {return Todo(id: id ?? this.id,title: title ?? this.title,completed: completed ?? this.completed,createdAt: createdAt ?? this.createdAt,);}Map<String, dynamic> toMap() {return {'id': id,'title': title,'completed': completed,'createdAt': createdAt.millisecondsSinceEpoch,};}factory Todo.fromMap(Map<String, dynamic> map) {return Todo(id: map['id'],title: map['title'],completed: map['completed'],createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt']),);}
}
// lib/providers/todo_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:uuid/uuid.dart';
import '../models/todo_model.dart';
import '../services/distributed_kv_service.dart';final todoListProvider = StateNotifierProvider<TodoListNotifier, List<Todo>>((ref) {return TodoListNotifier();
});class TodoListNotifier extends StateNotifier<List<Todo>> {TodoListNotifier() : super([]) {_loadFromDistributedStorage();}Future<void> _loadFromDistributedStorage() async {final data = await DistributedKVService.get('todos');if (data != null) {final List<dynamic> jsonList = json.decode(data);final todos = jsonList.map((item) => Todo.fromMap(item)).toList();state = todos;}}Future<void> _saveToDistributedStorage() async {final jsonList = state.map((todo) => todo.toMap()).toList();await DistributedKVService.save('todos', json.encode(jsonList));}void addTodo(String title) {final newTodo = Todo(id: const Uuid().v4(),title: title,createdAt: DateTime.now(),);state = [...state, newTodo];_saveToDistributedStorage();}void toggleTodo(String id) {state = state.map((todo) {if (todo.id == id) {return todo.copyWith(completed: !todo.completed);}return todo;}).toList();_saveToDistributedStorage();}void deleteTodo(String id) {state = state.where((todo) => todo.id != id).toList();_saveToDistributedStorage();}void updateTodo(String id, String newTitle) {state = state.map((todo) {if (todo.id == id) {return todo.copyWith(title: newTitle);}return todo;}).toList();_saveToDistributedStorage();}
}
// lib/pages/todo_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/todo_provider.dart';class TodoPage extends ConsumerWidget {const TodoPage({super.key});@overrideWidget build(BuildContext context, WidgetRef ref) {final todos = ref.watch(todoListProvider);final notifier = ref.read(todoListProvider.notifier);return Scaffold(appBar: AppBar(title: const Text('待办事项'),actions: [IconButton(icon: const Icon(Icons.delete),onPressed: () {// 清空已完成final completedIds = todos.where((todo) => todo.completed).map((todo) => todo.id).toList();for (final id in completedIds) {notifier.deleteTodo(id);}},),],),body: ListView.builder(itemCount: todos.length,itemBuilder: (context, index) {final todo = todos[index];return ListTile(leading: Checkbox(value: todo.completed,onChanged: (value) => notifier.toggleTodo(todo.id),),title: Text(todo.title,style: todo.completed? TextStyle(decoration: TextDecoration.lineThrough): null,),trailing: IconButton(icon: const Icon(Icons.delete),onPressed: () => notifier.deleteTodo(todo.id),),onTap: () => _editTodo(context, notifier, todo),);},),floatingActionButton: FloatingActionButton(onPressed: () => _addTodo(context, notifier),child: const Icon(Icons.add),),);}void _addTodo(BuildContext context, TodoListNotifier notifier) {showDialog(context: context,builder: (context) {final controller = TextEditingController();return AlertDialog(title: const Text('添加待办'),content: TextField(controller: controller,decoration: const InputDecoration(hintText: '输入待办事项'),),actions: [TextButton(onPressed: () => Navigator.pop(context),child: const Text('取消'),),TextButton(onPressed: () {if (controller.text.isNotEmpty) {notifier.addTodo(controller.text);Navigator.pop(context);}},child: const Text('添加'),),],);},);}void _editTodo(BuildContext context, TodoListNotifier notifier, Todo todo) {showDialog(context: context,builder: (context) {final controller = TextEditingController(text: todo.title);return AlertDialog(title: const Text('编辑待办'),content: TextField(controller: controller,decoration: const InputDecoration(hintText: '输入待办事项'),),actions: [TextButton(onPressed: () => Navigator.pop(context),child: const Text('取消'),),TextButton(onPressed: () {if (controller.text.isNotEmpty) {notifier.updateTodo(todo.id, controller.text);Navigator.pop(context);}},child: const Text('保存'),),],);},);}
}

六、总结与关键要点

通过本篇的学习,你应该已经掌握了:

  1. 状态管理方案选型:Provider、Riverpod等主流方案的特点和适用场景
  2. 数据持久化技术:SharedPreferences、Hive、SQLite的完整实现
  3. 鸿蒙分布式数据:分布式键值存储和对象存储的跨设备同步
  4. 最佳实践:状态分层架构、持久化策略、状态恢复机制

核心价值:通过状态管理和分布式数据同步,你的Flutter应用可以在鸿蒙生态中实现真正的跨设备无缝体验。用户在一台设备上操作的数据,可以实时同步到其他设备,大大提升了应用的使用体验。

下一篇预告:我们将深入探讨网络请求、API集成与离线缓存,学习如何在Flutter应用中实现高效的网络通信和离线数据管理,让你的应用在网络不稳定的环境下依然能够流畅运行。

http://www.jsqmd.com/news/94553/

相关文章:

  • React Native鸿蒙开发实战(四):路由导航与多页面应用 - 青青子衿-
  • 【DOTS物理系统深度解析】:掌握高性能物理模拟的5大核心技巧
  • 错过将后悔!R量子模拟中不可不知的门序列设计原则
  • 【资深架构师亲授】:构建零容错API——Symfony 8路由参数验证全流程控制
  • 刷题日记day6(数学)
  • 吴恩达深度学习课程四:计算机视觉 第二周:经典网络结构 (一)经典卷积网络
  • 【Flutter x 鸿蒙】第四篇:双向通信——Flutter调用鸿蒙原生能力 - 青青子衿-
  • 【医疗数据监管新规应对指南】:基于PHP的实时审计日志监控系统搭建
  • 锂离子电池二阶等效电路模型,基于MATLAB SIMULINK模块搭建,模型中包含一套完整的二...
  • Java毕设项目:基于springboot工资管理系统(源码+文档,讲解、调试运行,定制等)
  • LangChain 1.0 Agent开发实战:从入门到智能运行体构建!
  • 美国银行可以“炒币”了?加密货币公司“持证”开启金融新玩法!
  • 【R Shiny多模态数据导入终极指南】:掌握5种高效组件实现无缝数据集成
  • concaveman
  • 2025最新模温机供应商厂家推荐排行榜
  • 基于STM32智能营养称系统的设计与实现_352
  • Java毕设项目:基于SpringBoot+Vue高校奖学金评定管理系统设计与实现基于springboot高校学生奖学金评定系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • 2025年12月尼龙扎带厂家推荐,全场景真实调研口碑数据化解析,尼龙扎带 不锈钢扎带 线卡 十字架 定位片 瓷砖找平器 梅花管 扎丝带测评! - 品牌鉴赏师
  • 一文详解「全面向加密货币转型」的 Robinhood 最新基本面及收入来源
  • 医疗数据泄露风险激增?,紧急应对PHP脱敏新规调整
  • Laravel 13多模态文档实战指南(9大核心功能全曝光)
  • 日志堆积导致系统崩溃?连接器日志优化的3大黄金法则
  • 汇川H5U标准化编程模板!! 逻辑非常清晰,对规范化编程很有参考价值!!! 1.注释详细,功能齐全,逻辑严谨 2.软元件命名,地址规划规范 3.启停、报警总结、光电检测程序完整 4.气缸、轴控功能块编
  • 还在为监测点稀疏发愁?R语言克里金插值让你的数据“无中生有”
  • 智能运维(AIOps)平台综合评测与选型指南(2025)
  • thupc2026初赛题解
  • 模温机制造企业口碑排行榜:2025最新
  • 罗德与施瓦茨示波器在射频测试中的应用
  • 紧急预警:不解决这4个PHP网关协议问题,你的农业物联网系统将瘫痪
  • 【企业数字化转型新引擎】:量子服务集成带来的4倍效能提升秘诀