Flutter 开发鸿蒙应用:状态管理与分布式数据同步实战
作者链接:哇是林啊标签:#harmonyos #flutter #状态管理 #分布式数据 #provider
在上一篇文章中,我们完成了鸿蒙与 Flutter 的基础集成和原生通信。本文将聚焦更复杂的实战场景:使用 Provider 进行 Flutter 状态管理,并结合鸿蒙分布式数据管理(DataShare)实现多设备数据同步。通过完整的代码案例,讲解从数据建模、状态管理到分布式同步的全流程,助力开发者构建高性能、多设备适配的鸿蒙 - Flutter 应用。
一、核心技术选型说明
- 状态管理:Provider 6.0+(轻量、易集成,适合中小型应用的状态共享)
- 分布式数据:鸿蒙 DataShare(基于鸿蒙分布式能力,支持多设备数据实时同步)
- 网络 / 存储:shared_preferences(Flutter 端本地存储)+ 鸿蒙 DataShare SDK
- 开发环境:延续上一篇的配置(DevEco Studio 4.0+ + Flutter 3.13+)
二、项目基础架构搭建
2.1 依赖添加
在flutter_module/pubspec.yaml中添加 Provider 和 shared_preferences 依赖:
yaml
dependencies:
flutter:
sdk: flutter
provider: ^6.1.1
shared_preferences: ^2.2.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
执行flutter pub get安装依赖。
2.2 数据模型定义
创建flutter_module/lib/model/user_model.dart,定义用户数据模型(用于状态管理和分布式同步):
dart
class UserModel {
final String userId;
String userName;
int age;
String deviceId; // 记录数据所属设备ID
UserModel({
required this.userId,
required this.userName,
required this.age,
required this.deviceId,
});
// 转JSON(用于与鸿蒙DataShare通信)
Map<String, dynamic> toJson() => {
'userId': userId,
'userName': userName,
'age': age,
'deviceId': deviceId,
};
// 从JSON构建对象
static UserModel fromJson(Map<String, dynamic> json) => UserModel(
userId: json['userId'],
userName: json['userName'],
age: json['age'],
deviceId: json['deviceId'],
);
}
三、基于 Provider 的状态管理实现
3.1 创建状态管理类
创建flutter_module/lib/provider/user_provider.dart,封装用户数据的状态管理逻辑:
dart
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/services.dart';
import '../model/user_model.dart';
class UserProvider extends ChangeNotifier {
UserModel? _currentUser;
static const MethodChannel _dataShareChannel = MethodChannel('com.example.harmony_flutter/datashare');
UserModel? get currentUser => _currentUser;
// 初始化:从本地存储或分布式数据加载用户信息
Future<void> initUser() async {
// 1. 先从本地存储加载
final prefs = await SharedPreferences.getInstance();
final userJson = prefs.getString('current_user');
if (userJson != null) {
_currentUser = UserModel.fromJson({'userId': '', 'userName': '', 'age': 0, 'deviceId': ''}..addAll(await _dataShareChannel.invokeMethod('getUser')));
notifyListeners();
return;
}
// 2. 本地无数据时,从鸿蒙分布式数据加载
try {
final result = await _dataShareChannel.invokeMethod('getUser');
if (result != null) {
_currentUser = UserModel.fromJson(result);
// 同步到本地存储
await prefs.setString('current_user', result.toString());
}
} catch (e) {
debugPrint('从分布式数据加载失败:$e');
}
notifyListeners();
}
// 更新用户信息(同步到本地和分布式数据)
Future<void> updateUser({required String userName, required int age}) async {
if (_currentUser == null) return;
// 更新内存状态
_currentUser!.userName = userName;
_currentUser!.age = age;
notifyListeners();
// 同步到本地存储
final prefs = await SharedPreferences.getInstance();
await prefs.setString('current_user', _currentUser!.toJson().toString());
// 同步到鸿蒙分布式数据
try {
await _dataShareChannel.invokeMethod('updateUser', _currentUser!.toJson());
} catch (e) {
debugPrint('同步到分布式数据失败:$e');
}
}
}
3.2 在 Flutter 应用中注入 Provider
修改flutter_module/lib/main.dart,通过ChangeNotifierProvider注入状态管理:
dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'provider/user_provider.dart';
import 'pages/user_info_page.dart';
void main() => runApp(
// 注入Provider
ChangeNotifierProvider(
create: (context) => UserProvider()..initUser(),
child: const MyApp(),
),
);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '鸿蒙-Flutter分布式Demo',
theme: ThemeData(primarySwatch: Colors.green),
home: const UserInfoPage(),
);
}
}
3.3 编写 Flutter 页面(状态共享与更新)
创建flutter_module/lib/pages/user_info_page.dart,实现用户信息展示和编辑功能:
dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../provider/user_provider.dart';
class UserInfoPage extends StatefulWidget {
const UserInfoPage({super.key});
@override
State<UserInfoPage> createState() => _UserInfoPageState();
}
class _UserInfoPageState extends State<UserInfoPage> {
final TextEditingController _nameController = TextEditingController();
final TextEditingController _ageController = TextEditingController();
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 从Provider获取用户信息并填充到输入框
final user = Provider.of<UserProvider>(context).currentUser;
if (user != null) {
_nameController.text = user.userName;
_ageController.text = user.age.toString();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('用户信息管理(分布式同步)')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Consumer<UserProvider>(
builder: (context, provider, child) {
final user = provider.currentUser;
if (user == null) {
return const Center(child: CircularProgressIndicator());
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 显示设备ID(标识数据来源设备)
Text('当前设备ID:${user.deviceId}', style: const TextStyle(color: Colors.grey)),
const SizedBox(height: 20),
TextField(
controller: _nameController,
decoration: const InputDecoration(labelText: '用户名'),
),
const SizedBox(height: 16),
TextField(
controller: _ageController,
decoration: const InputDecoration(labelText: '年龄'),
keyboardType: TextInputType.number,
),
const SizedBox(height: 30),
Center(
child: ElevatedButton(
onPressed: () {
final name = _nameController.text.trim();
final age = int.tryParse(_ageController.text.trim()) ?? 0;
if (name.isNotEmpty) {
provider.updateUser(userName: name, age: age);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('信息更新成功,已同步到所有设备')),
);
}
},
child: const Text('更新信息(分布式同步)'),
),
),
],
);
},
),
),
);
}
@override
void dispose() {
_nameController.dispose();
_ageController.dispose();
super.dispose();
}
}
四、鸿蒙分布式数据同步(DataShare)实现
4.1 鸿蒙端 DataShare 服务配置
(1)创建 DataShare 能力
在鸿蒙项目中创建entry/src/main/java/com/example/harmony_flutter_demo/datashare目录,创建UserDataShare.java:
java
运行
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.data.dataability.DataAbilityHelper;
import ohos.data.dataability.DataAbilityRemoteException;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;
import ohos.data.resultset.ResultSet;
import ohos.data.valueset.ValueSet;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.system.DeviceInfo;
import java.util.HashMap;
import java.util.Map;
public class UserDataShare extends Ability {
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00100, "UserDataShare");
private static final String DB_NAME = "user_db.db";
private static final int DB_VERSION = 1;
private static final String TABLE_NAME = "user";
private RdbStore rdbStore;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// 初始化数据库
initRdbStore();
}
// 初始化RDB数据库
private void initRdbStore() {
StoreConfig config = StoreConfig.newDefaultConfig(DB_NAME);
RdbOpenCallback callback = new RdbOpenCallback() {
@Override
public void onCreate(RdbStore store) {
// 创建用户表
store.executeSql("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
"userId TEXT PRIMARY KEY, " +
"userName TEXT, " +
"age INTEGER, " +
"deviceId TEXT)");
// 初始化默认用户数据
String deviceId = DeviceInfo.getDeviceId();
ValueSet valueSet = new ValueSet();
valueSet.putString("userId", "default_user");
valueSet.putString("userName", "默认用户");
valueSet.putInteger("age", 20);
valueSet.putString("deviceId", deviceId);
store.insert(TABLE_NAME, valueSet);
}
@Override
public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {}
};
rdbStore = openRdbStore(config, DB_VERSION, callback, null);
}
// 获取用户信息(供Flutter调用)
public Map<String, Object> getUserInfo() {
Map<String, Object> userMap = new HashMap<>();
try {
ResultSet resultSet = rdbStore.query(TABLE_NAME, null, null, null, null, null, null);
if (resultSet.moveToFirst()) {
userMap.put("userId", resultSet.getString(resultSet.getColumnIndexForName("userId")));
userMap.put("userName", resultSet.getString(resultSet.getColumnIndexForName("userName")));
userMap.put("age", resultSet.getInt(resultSet.getColumnIndexForName("age")));
userMap.put("deviceId", resultSet.getString(resultSet.getColumnIndexForName("deviceId")));
}
resultSet.close();
} catch (Exception e) {
HiLog.error(LABEL, "获取用户信息失败:%s", e.getMessage());
}
return userMap;
}
// 更新用户信息(供Flutter调用)
public boolean updateUserInfo(Map<String, Object> userMap) {
try {
ValueSet valueSet = new ValueSet();
valueSet.putString("userName", (String) userMap.get("userName"));
valueSet.putInteger("age", (Integer) userMap.get("age"));
valueSet.putString("deviceId", DeviceInfo.getDeviceId());
// 条件:更新默认用户
String whereClause = "userId = ?";
String[] whereArgs = {"default_user"};
return rdbStore.update(TABLE_NAME, valueSet, whereClause, whereArgs) > 0;
} catch (Exception e) {
HiLog.error(LABEL, "更新用户信息失败:%s", e.getMessage());
return false;
}
}
}
(2)注册 DataShare 服务
在entry/src/main/module.json5中注册 DataShare 能力:
json
{
"module": {
"abilities": [
{
"name": "com.example.harmony_flutter_demo.datashare.UserDataShare",
"type": "data",
"uri": "dataability://com.example.harmony_flutter_demo.UserDataShare",
"skills": [
{
"entities": ["ohos.utils.data.DataAbility"],
"actions": ["ohos.want.action.GET_DATA", "ohos.want.action.SET_DATA"]
}
]
}
]
}
}
4.2 扩展 MethodChannel 支持分布式数据通信
修改鸿蒙端的FlutterMethodCallHandler.java,添加 DataShare 相关方法处理:
java
运行
import com.example.harmony_flutter_demo.datashare.UserDataShare;
import java.util.Map;
public class FlutterMethodCallHandler implements MethodChannel.MethodCallHandler {
private final Ability ability;
private UserDataShare userDataShare;
public FlutterMethodCallHandler(Ability ability) {
this.ability = ability;
// 初始化DataShare
this.userDataShare = new UserDataShare();
this.userDataShare.onStart(null);
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "getDeviceInfo":
// 上一篇的设备信息获取逻辑
Map<String, String> deviceInfo = new HashMap<>();
deviceInfo.put("deviceName", DeviceInfo.getDeviceName());
deviceInfo.put("deviceModel", DeviceInfo.getDeviceModel());
result.success(deviceInfo);
break;
case "getUser":
// 获取分布式用户信息
result.success(userDataShare.getUserInfo());
break;
case "updateUser":
// 更新分布式用户信息
Map<String, Object> userMap = (Map<String, Object>) call.arguments;
boolean success = userDataShare.updateUserInfo(userMap);
result.success(success);
break;
default:
result.notImplemented();
break;
}
}
}
五、功能测试与验证
5.1 测试步骤
- 启动两台鸿蒙设备(或模拟器),确保已登录同一华为账号并开启分布式能力
- 在两台设备上分别运行应用,初始状态会加载默认用户信息
- 在其中一台设备上修改用户名和年龄,点击 "更新信息" 按钮
- 切换到另一台设备,刷新页面(或重新进入应用),可看到信息已同步更新
5.2 关键验证点
- 本地存储同步:修改后重启应用,信息不会丢失(shared_preferences 生效)
- 分布式同步:多设备登录同一账号时,数据实时同步(DataShare 生效)
- 状态管理:修改信息后,页面无需手动刷新即可更新(Provider 生效)
总结
本文通过 Provider 实现了 Flutter 端的状态管理,结合鸿蒙 DataShare 能力完成了多设备数据同步,构建了一个具备分布式特性的跨平台应用。核心亮点在于:
- 状态管理与分布式同步解耦:Provider 负责本地状态管理,鸿蒙 DataShare 负责跨设备同步,架构清晰
- 数据一致性保障:本地存储与分布式存储双向同步,确保离线场景下的数据可用性
- 原生能力深度集成:Flutter 通过 MethodChannel 无缝调用鸿蒙分布式 API,充分发挥鸿蒙生态优势
后续可扩展的方向:添加数据同步状态监听(如同步中、同步失败提示)、支持多用户数据管理、集成鸿蒙分布式文件服务实现文件同步等。如果需要进一步深入某个技术点,欢迎在评论区留言交流!
更多推荐


所有评论(0)