1. 项目背景与核心需求
口腔护理类App在移动健康领域一直有着稳定的需求。随着鸿蒙系统的崛起和React Native技术的成熟,开发一个能同时覆盖iOS、Android和HarmonyOS三大平台的口腔健康管理工具变得可行且必要。这个"今日任务"功能模块,本质上是要解决三个核心问题:
- 跨平台一致性:如何用同一套代码在三个系统上实现完全一致的用户体验
- 数据同步可靠性:用户的口腔护理记录需要在不同设备间实时同步
- 交互友好性:将专业的口腔护理知识转化为普通用户易理解的每日任务
我去年参与过一个类似的健康管理项目,当时最大的教训就是低估了不同平台间动画性能的差异。这次我们选择React Native+鸿蒙的方案,正是看中了其在保持跨平台特性的同时,对原生性能的优化能力。
2. 技术架构设计
2.1 跨平台方案选型
为什么选择React Native而不是Flutter或其他方案?主要基于三点考量:
- 团队技术栈:现有团队有丰富的React开发经验
- 鸿蒙适配成本:华为提供的react-native-harmony兼容层已经相对成熟
- 生态支持:口腔健康领域常用的图表库(如Victory Native)对RN支持更好
技术栈组合:
- 前端:React Native 0.72 + react-native-harmony
- 状态管理:Zustand(考虑到需要频繁更新任务状态)
- 导航:React Navigation 6.x
- 动画:Reanimated 3
2.2 数据层设计
口腔护理任务有其特殊性 - 既需要结构化数据(如刷牙时长),也需要非结构化数据(如口腔照片)。我们的数据模型这样设计:
interface DailyTask { id: string; date: string; completed: boolean; tasks: { brushing: { duration: number; // 单位:秒 areasMissed: string[]; // 遗漏区域 }; flossing: boolean; mouthwash: boolean; photos?: { front: string; left: string; right: string; }; }; reminders: { morning: string; evening: string; }; }使用WatermelonDB作为本地数据库,配合自定义的同步引擎实现多设备同步。这里有个关键点:口腔照片的同步需要特殊处理,我们采用先压缩后分块上传的策略。
3. 核心功能实现
3.1 任务卡片组件
这是"今日任务"的核心UI,需要实现:
- 进度环形图(显示完成率)
- 可交互的任务项
- 平滑的完成动画
const TaskCard = ({ tasks }: { tasks: DailyTask }) => { const progress = useMemo(() => { const total = Object.keys(tasks.tasks).length; const completed = Object.values(tasks.tasks).filter(Boolean).length; return completed / total; }, [tasks]); return ( <View style={styles.card}> <AnimatedCircularProgress size={120} width={10} fill={progress * 100} tintColor="#4CB050" backgroundColor="#E0E0E0"> {() => ( <Text style={styles.progressText}> {Math.round(progress * 100)}% </Text> )} </AnimatedCircularProgress> <TaskItem icon="toothbrush" title="刷牙2分钟" completed={tasks.tasks.brushing.duration >= 120} onPress={() => /* 跳转到刷牙指导 */} /> {/* 其他任务项 */} </View> ); };3.2 刷牙指导模块
这是最具挑战的部分,需要:
- 使用手机传感器检测刷牙动作
- 通过面部识别确定刷牙区域
- 实时反馈刷牙质量
我们借助react-native-sensors获取加速度计数据,结合简单的机器学习模型识别刷牙动作:
const { accelerometer } = useSensors(); useEffect(() => { const subscription = accelerometer.subscribe(({ x, y, z }) => { // 简单的动作识别逻辑 const intensity = Math.sqrt(x*x + y*y + z*z); if (intensity > 1.5) { dispatch({ type: 'BRUSHING_DETECTED' }); } }); return () => subscription.unsubscribe(); }, []);对于区域检测,我们使用华为ML Kit的面部特征识别:
// 在鸿蒙侧通过Native Module暴露的接口 @ReactMethod public void startFaceDetection(Promise promise) { MLFaceAnalyzer analyzer = MLAnalyzerFactory.getInstance() .getFaceAnalyzer(new MLFaceAnalyzerSetting.Factory() .setFeatureType(MLFaceAnalyzerSetting.TYPE_FEATURES) .create()); // ... 实现代码 }4. 跨平台适配要点
4.1 鸿蒙特有组件处理
鸿蒙的某些UI组件与Android/iOS有差异,需要特殊处理:
const ToothIcon = () => { return Platform.select({ harmony: <harmony.toothIcon size={24} />, default: <Ionicons name="md-tooth" size={24} /> }); };4.2 性能优化策略
- 列表优化:使用FlashList替代FlatList
- 图片处理:对口腔照片使用渐进式加载
- 内存管理:特别要注意鸿蒙后台状态的内存回收机制
// 在应用进入后台时主动清理缓存 AppState.addEventListener('change', (state) => { if (state === 'background') { ImageCacheManager.clearCache(); } });5. 测试与调试
5.1 跨平台测试矩阵
我们建立了这样的测试流程:
| 测试类型 | iOS | Android | HarmonyOS |
|---|---|---|---|
| 功能测试 | ✓ | ✓ | ✓ |
| 性能测试 | ✓ | ✓ | 重点 |
| 传感器测试 | ✓ | ✓ | 特殊 |
| 后台同步测试 | ✓ | ✓ | 重点 |
5.2 常见问题排查
鸿蒙上动画卡顿:
- 检查是否使用了不支持的动画属性
- 尝试使用react-native-harmony提供的优化组件
传感器数据不一致:
- 不同设备的采样率差异
- 需要做数据归一化处理
照片同步失败:
- 检查鸿蒙的文件系统权限
- 确认分块上传的chunk大小设置合理
6. 项目部署与监控
6.1 应用发布策略
采用分阶段发布:
- 先上架Android版本验证核心功能
- 一周后发布iOS版本
- 鸿蒙版本作为独立应用上架华为应用市场
6.2 关键监控指标
- 任务完成率
- 刷牙时长分布
- 跨设备同步成功率
- 鸿蒙特定崩溃率
我们使用React Native的ErrorMonitor配合华为的AGC崩溃服务:
import { ErrorMonitor } from 'react-native-harmony'; ErrorMonitor.setHandler((error) => { // 上报到华为AGC HMSLogger.getInstance().sendErrorLog(error); });7. 项目经验总结
这个项目给我最深的体会是:跨平台开发不是简单的"一次编写,到处运行",而是需要深入理解每个平台的特性。特别是在鸿蒙平台上,以下几点特别重要:
- 线程模型差异:鸿蒙的Worker实现与Android不同
- 动画性能:需要适当降低动画复杂度
- 权限系统:鸿蒙的权限申请时机更严格
一个实用的技巧:在开发阶段,我建议在代码中增加平台特性标记:
const isHarmony = Platform.OS === 'harmony'; const isHarmony2 = isHarmony && Platform.constants.harmonyVersion >= 2;这样可以根据不同鸿蒙版本做更精细的适配。