Flutter三方库适配OpenHarmony【secure_application】— MethodChannel 通信协议设计
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.netMethodChannel 是 Dart 层和原生层之间的桥梁。secure_application 的通信协议比 flutter_speech 简单得多——只有5个 Dart→Native 方法和2个 Native→Dart 事件。但简单不代表可以随意设计,通道名称、参数格式、返回值约定
前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
MethodChannel 是 Dart 层和原生层之间的桥梁。secure_application 的通信协议比 flutter_speech 简单得多——只有5个 Dart→Native 方法和2个 Native→Dart 事件。但简单不代表可以随意设计,通道名称、参数格式、返回值约定都需要严格一致。
今天把完整的通信协议梳理清楚。
一、通道注册与名称约定
1.1 通道名称
// Native 端
new MethodChannel(binding.getBinaryMessenger(), "secure_application");
// Dart 端
static const MethodChannel _channel = const MethodChannel('secure_application');
通道名称 "secure_application" 在两端必须完全一致,包括大小写和空格。
1.2 与 flutter_speech 的对比
| 插件 | 通道名称 | 命名风格 |
|---|---|---|
| flutter_speech | com.flutter.speech_recognition |
Java 包名风格 |
| secure_application | secure_application |
简单下划线风格 |
两种命名风格都可以,没有强制规范。但建议保持项目内一致。
1.3 通道的生命周期
onAttachedToEngine
│
├── new MethodChannel(...) ← 创建通道
├── channel.setMethodCallHandler(this) ← 注册处理器
│
│ ... 通道活跃,可以双向通信 ...
│
onDetachedFromEngine
│
├── channel.setMethodCallHandler(null) ← 移除处理器
└── channel = null ← 释放通道
二、Dart → Native 方法调用
2.1 五个方法总览
| 方法名 | 参数 | 返回值 | 触发时机 |
|---|---|---|---|
secure |
无(或 opacity) | true | 用户调用 controller.secure() |
open |
无 | true | 用户调用 controller.open() |
lock |
无 | true | controller.lock() |
unlock |
无 | true | controller.unlock() |
opacity |
{“opacity”: double} | true | SecureGate 初始化或 opacity 变化 |
2.2 Dart 端调用代码
class SecureApplicationNative {
static const MethodChannel _channel = const MethodChannel('secure_application');
static Future secure() => _channel.invokeMethod('secure');
static Future open() => _channel.invokeMethod('open');
static Future lock() => _channel.invokeMethod('lock');
static Future unlock() => _channel.invokeMethod('unlock');
static Future opacity(double opacity) =>
_channel.invokeMethod('opacity', {"opacity": opacity});
}
2.3 参数传递
只有 opacity 方法带参数:
// Dart 端发送
_channel.invokeMethod('opacity', {"opacity": 0.6});
// Native 端接收
case "opacity":
const newOpacity: number = call.argument("opacity");
if (newOpacity != null && newOpacity != undefined) {
this.opacity = newOpacity;
}
result.success(true);
break;
| 字段 | 类型 | 范围 | 说明 |
|---|---|---|---|
| opacity | double/number | 0.0 ~ 1.0 | 遮罩透明度 |
2.4 secure 方法的可选参数
case "secure":
this.secured = true;
try {
const secureOpacity: number = call.argument("opacity");
if (secureOpacity != null && secureOpacity != undefined) {
this.opacity = secureOpacity;
}
} catch (e) {
// No opacity argument passed, use default
}
this.setPrivacyMode(true);
result.success(true);
break;
secure 方法可以可选地携带 opacity 参数。当前 Dart 层没有传这个参数,但原生端做了兼容处理。
三、Native → Dart 事件回调
3.1 两个事件
| 事件名 | 参数 | 触发时机 |
|---|---|---|
lock |
null | 窗口失焦或应用进入后台 |
unlock |
null | (当前未使用) |
3.2 Native 端发送
// 窗口失焦时
this.channel.invokeMethod("lock", null);
// 应用进入后台时
this.channel.invokeMethod("lock", null);
3.3 Dart 端接收
static Future<dynamic> secureApplicationHandler(
MethodCall methodCall, lock, unlock) async {
switch (methodCall.method) {
case 'lock':
lock(); // 调用 controller.lockIfSecured()
break;
case 'unlock':
unlock(); // 调用 controller.unlock()
break;
default:
throw MissingPluginException('notImplemented');
}
}
3.4 与 flutter_speech 的对比
| 维度 | flutter_speech | secure_application |
|---|---|---|
| Native→Dart 事件数 | 5个 | 2个 |
| 事件携带数据 | 有(识别文本等) | 无(null) |
| 事件频率 | 高(实时识别结果) | 低(只在切换时) |
| 复杂度 | 高 | 低 |
💡 secure_application 的 Native→Dart 通信非常简单——只需要告诉 Dart 层"该锁了"或"该解锁了",不需要传递任何数据。
四、通信时序图
4.1 开启保护
Dart Native 系统
│ │ │
│──secure()─────────────►│ │
│ │──setPrivacyMode(true)─►│
│ │◄──────Promise.resolve──│
│◄──result.success(true)─│ │
4.2 用户切后台
用户 系统 Native Dart SecureGate
│ │ │ │ │
│─Home──►│ │ │ │
│ │─INACTIVE►│ │ │
│ │ │──lock──────────►│ │
│ │ │ │──lockIfSecured►│
│ │─BG─────►│ │ │──显示遮罩
│ │ │──lock──────────►│ │
│ │ │ │──(防重入跳过) │
4.3 用户切回前台
用户 系统 Native Dart SecureGate
│ │ │ │ │
│─切回──►│ │ │ │
│ │─FG─────►│ │ │
│ │ │──(不操作) │ │
│ │ │ │ │
│ │ │ Flutter: resumed │
│ │ │ │──onNeedUnlock │
│ │ │ │ (认证流程) │
│ │ │ │──authSuccess │
│ │ │ │──unlock───────►│
│ │ │◄──unlock───────│ │──隐藏遮罩
4.4 关闭保护
Dart Native 系统
│ │ │
│──open()───────────────►│ │
│ │──setPrivacyMode(false)►│
│ │◄──────Promise.resolve──│
│◄──result.success(true)─│ │
五、返回值约定
5.1 所有方法都返回 true
case "secure":
// ... 逻辑 ...
result.success(true);
break;
case "open":
// ... 逻辑 ...
result.success(true);
break;
// 甚至 default 也返回 true
default:
result.success(true);
break;
5.2 为什么不返回操作结果
| 方案 | 优点 | 缺点 |
|---|---|---|
| 始终返回 true | 简单,Dart 层不需要处理失败 | 无法知道操作是否真正成功 |
| 返回实际结果 | 精确,可以做降级处理 | Dart 层需要额外的错误处理逻辑 |
secure_application 选择了始终返回 true,因为:
- 隐私模式设置是异步的,
result.success时可能还没完成 - 即使原生端失败,Dart 层的模糊遮罩仍然有效
- 简化了 Dart 层的代码
5.3 default 分支的处理
// secure_application:default 返回 true
default:
result.success(true);
break;
// flutter_speech:default 返回 notImplemented
default:
result.notImplemented();
break;
| 处理方式 | 效果 | 适用场景 |
|---|---|---|
| result.success(true) | Dart 层不会报错 | 容错优先 |
| result.notImplemented() | Dart 层抛出 MissingPluginException | 严格模式 |
📌 secure_application 的 default 返回 true 是一种容错设计——即使 Dart 层发送了未知方法,也不会导致异常。但这也意味着拼写错误不容易被发现。
六、opacity 参数的跨层传递
6.1 完整链路
SecureGate.initState()
│
▼
SecureApplicationNative.opacity(0.6)
│
▼
_channel.invokeMethod('opacity', {"opacity": 0.6})
│
▼ MethodChannel
│
onMethodCall(call, result)
│ case "opacity"
▼
call.argument("opacity") → 0.6
│
▼
this.opacity = 0.6
6.2 类型安全
const newOpacity: number = call.argument("opacity");
call.argument("opacity") 返回的是 Object 类型,需要转换为 number。如果 Dart 层传的不是数字,这里可能得到 null 或异常。
6.3 防御性编程
try {
const newOpacity: number = call.argument("opacity");
if (newOpacity != null && newOpacity != undefined) {
this.opacity = newOpacity;
}
} catch (e) {
Log.e(TAG, "Failed to parse opacity argument");
}
三层防御:
- try-catch 捕获类型转换异常
- null 检查
- undefined 检查
七、通信协议的完整清单
7.1 Dart → Native
| # | 方法 | 参数 | 原生行为 | 返回值 |
|---|---|---|---|---|
| 1 | secure | 无/opacity | setPrivacyMode(true) | true |
| 2 | open | 无 | setPrivacyMode(false) | true |
| 3 | lock | 无 | 空实现 | true |
| 4 | unlock | 无 | 空实现 | true |
| 5 | opacity | {“opacity”: double} | 保存 opacity 值 | true |
7.2 Native → Dart
| # | 事件 | 参数 | Dart 行为 |
|---|---|---|---|
| 1 | lock | null | lockIfSecured() |
| 2 | unlock | null | unlock() |
7.3 通道信息
| 属性 | 值 |
|---|---|
| 通道名称 | “secure_application” |
| 编码方式 | StandardMethodCodec |
| 通信方向 | 双向 |
总结
本文梳理了 secure_application 的完整 MethodChannel 通信协议:
- 5个 Dart→Native 方法:secure、open、lock、unlock、opacity
- 2个 Native→Dart 事件:lock、unlock
- 参数传递:只有 opacity 带参数,其他都无参数
- 返回值:所有方法统一返回 true
- 通信频率:低频通信,只在状态切换时触发
下一篇我们详细分析 onMethodCall 的方法分发实现——每个 case 分支的具体逻辑。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- Flutter MethodChannel 文档
- StandardMethodCodec
- Flutter Platform Channels
- secure_application 源码
- secure_application OpenHarmony 源码
- MethodCall.argument 文档
- ArkTS Promise 编程
- 开源鸿蒙跨平台社区

MethodChannel 双向通信示意图
更多推荐


所有评论(0)