1. 项目背景与核心需求
在移动应用开发领域,跨平台框架Flutter与国产操作系统OpenHarmony的结合正在形成新的技术趋势。这次我们要实现的是一个电子合同签署App的通知管理模块,这个功能在商务场景中具有关键作用。
电子合同签署过程中,用户需要实时接收合同状态变更、签署提醒、审批结果等重要通知。传统实现方式往往面临以下痛点:
- 不同厂商设备推送服务不兼容
- 通知样式难以统一
- 离线消息无法可靠送达
- 用户行为追踪困难
2. 技术选型与架构设计
2.1 Flutter与OpenHarmony的适配方案
在OpenHarmony上运行Flutter应用需要解决几个关键问题:
- 渲染引擎适配:通过修改Flutter引擎的Skia绘制后端,使其调用OHOS的图形接口
- 平台通道实现:重写MethodChannel和EventChannel,对接OHOS的Native API
- 插件生态兼容:为常用插件(如通知、存储等)开发OpenHarmony版本
具体到通知管理模块,我们采用分层架构:
应用层(Flutter Dart) ↓ 业务逻辑层(通知处理、状态管理) ↓ 适配层(平台通道封装) ↓ 原生层(OpenHarmony通知服务)2.2 通知服务核心组件
通知发布器:
- 支持即时通知和定时通知
- 提供多种优先级设置
- 支持富媒体内容(合同缩略图、签署人头像等)
消息队列:
- 使用SQLite实现本地消息存储
- 采用LRU缓存管理策略
- 支持消息去重和合并
状态同步器:
- 基于WebSocket实现实时同步
- 断网自动切换长轮询
- 采用差分更新减少流量消耗
3. 具体实现与关键技术
3.1 OpenHarmony通知通道配置
首先需要在config.json中声明通知权限:
{ "module": { "abilities": [ { "name": "NotificationService", "type": "service", "permissions": [ "ohos.permission.NOTIFICATION_CONTROLLER" ] } ] } }然后创建通知渠道(Android 8.0+和OpenHarmony的通用做法):
Future<void> createNotificationChannel() async { if (Platform.isAndroid || Platform.isOpenHarmony) { const channel = AndroidNotificationChannel( 'contract_sign_channel', '合同签署通知', importance: Importance.high, ); await FlutterLocalNotificationsPlugin() .resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); } }3.2 通知内容生成与触发
针对电子合同场景,我们设计了多种通知模板:
enum ContractNotificationType { newContract, // 新合同到达 signReminder, // 签署提醒 signComplete, // 签署完成 contractExpire, // 合同即将过期 } String _getNotificationTitle(ContractNotificationType type) { switch (type) { case ContractNotificationType.newContract: return '您有新的合同待签署'; case ContractNotificationType.signReminder: return '合同签署提醒'; case ContractNotificationType.signComplete: return '合同签署完成'; case ContractNotificationType.contractExpire: return '合同即将过期'; } }3.3 通知点击处理
在Flutter端注册通知点击回调:
final NotificationAppLaunchDetails? notificationAppLaunchDetails = await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails(); if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) { _handleNotificationOpen(notificationAppLaunchDetails!); } void _handleNotificationOpen(NotificationAppLaunchDetails details) { final payload = details.payload; if (payload != null) { final contractId = jsonDecode(payload)['contractId']; Navigator.push(context, ContractDetailPage(contractId)); } }4. 性能优化与特殊场景处理
4.1 通知去重机制
为避免重复通知打扰用户,实现基于内容指纹的去重:
class NotificationDeduplicator { final _cache = <String, DateTime>{}; bool shouldShow(String content) { final fingerprint = _generateFingerprint(content); if (_cache.containsKey(fingerprint)) { final lastShowTime = _cache[fingerprint]!; if (DateTime.now().difference(lastShowTime) < Duration(hours: 1)) { return false; } } _cache[fingerprint] = DateTime.now(); return true; } String _generateFingerprint(String content) { return md5.convert(utf8.encode(content)).toString(); } }4.2 离线消息处理
针对网络不稳定的情况,实现离线消息队列:
class OfflineNotificationQueue { final _queue = <Map<String, dynamic>>[]; final _maxRetry = 3; Future<void> addNotification(Map<String, dynamic> notification) async { _queue.add(notification); await _trySendAll(); } Future<void> _trySendAll() async { while (_queue.isNotEmpty) { final notification = _queue.first; try { await _sendNotification(notification); _queue.removeAt(0); } catch (e) { notification['retryCount'] = (notification['retryCount'] ?? 0) + 1; if (notification['retryCount'] >= _maxRetry) { _queue.removeAt(0); await _saveFailedNotification(notification); } break; } } } }5. 测试与验证方案
5.1 单元测试要点
针对通知管理模块的关键测试用例:
void main() { test('通知去重逻辑测试', () { final deduplicator = NotificationDeduplicator(); const content = '测试内容'; expect(deduplicator.shouldShow(content), isTrue); expect(deduplicator.shouldShow(content), isFalse); }); test('离线队列重试逻辑', () async { final queue = OfflineNotificationQueue(); await queue.addNotification({'title': '测试'}); expect(queue.length, equals(0)); // 假设网络正常 }); }5.2 真机测试场景
需要在以下场景验证通知功能:
- 应用在前台时收到通知
- 应用在后台时收到通知
- 应用被杀死后收到通知
- 网络从离线切换到在线时的消息同步
- 同时收到多条通知时的显示顺序
6. 常见问题与解决方案
6.1 OpenHarmony通知不显示
可能原因及排查步骤:
- 检查config.json中是否声明了通知权限
- 验证通知渠道是否创建成功
- 查看系统通知设置中是否禁用了应用通知
- 检查通知内容是否包含非法字符
6.2 通知点击无响应
调试方法:
- 确认通知payload格式正确
- 检查MainActivity是否配置了intent-filter
- 验证getNotificationAppLaunchDetails的返回值
- 检查路由跳转逻辑是否正确
6.3 性能优化建议
- 对于批量通知,使用合并通知方式
- 图片资源使用缩略图并缓存
- 高频通知采用摘要形式展示
- 合理设置通知过期时间
7. 扩展与演进方向
- 智能通知分类:基于合同类型和紧急程度自动分类
- 签名验证通知:集成数字证书验证功能
- 多端同步:实现PC端和移动端通知状态同步
- 语音播报:重要通知增加语音提示功能
在实现过程中发现,OpenHarmony的通知API与Android存在一些差异,需要特别注意:
- 通知图标必须使用像素图而非矢量图
- 最大优先级设置可能被系统限制
- 某些厂商设备可能有自定义限制
对于电子合同这类严肃场景,通知的可靠性和安全性至关重要。我们额外增加了以下保障措施:
- 关键操作通知必须包含数字签名
- 敏感内容通知在锁屏时隐藏详情
- 所有通知日志上传至区块链存证