Flutter三方库适配OpenHarmony【secure_application】— onMethodCall 方法分发实现
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net上一篇梳理了通信协议的全貌,这一篇把的每个 case 分支都拆开来看。secure_application 的方法分发逻辑不复杂,但每个分支背后的设计考量值得细说——特别是 lock/unlock 为什么是空实现,以及 opacity 的参数解析为什么要包三层防御。Dart 层的和会调用这
前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
上一篇梳理了通信协议的全貌,这一篇把 onMethodCall 的每个 case 分支都拆开来看。secure_application 的方法分发逻辑不复杂,但每个分支背后的设计考量值得细说——特别是 lock/unlock 为什么是空实现,以及 opacity 的参数解析为什么要包三层防御。
一、onMethodCall 完整实现
1.1 源码
onMethodCall(call: MethodCall, result: MethodResult): void {
switch (call.method) {
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;
case "open":
this.secured = false;
this.setPrivacyMode(false);
result.success(true);
break;
case "opacity":
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");
}
result.success(true);
break;
case "unlock":
result.success(true);
break;
case "lock":
result.success(true);
break;
default:
result.success(true);
break;
}
}
1.2 方法分类
| 类别 | 方法 | 有原生操作 |
|---|---|---|
| 核心方法 | secure, open | ✅ 控制隐私模式 |
| 参数方法 | opacity | ✅ 保存参数值 |
| 空实现 | lock, unlock | ❌ 直接返回 true |
| 兜底 | default | ❌ 直接返回 true |
二、secure 方法:开启保护
2.1 执行流程
case "secure":
this.secured = true; // 1. 设置标志位
try {
const secureOpacity: number = call.argument("opacity");
if (secureOpacity != null && secureOpacity != undefined) {
this.opacity = secureOpacity; // 2. 可选:更新透明度
}
} catch (e) {}
this.setPrivacyMode(true); // 3. 开启隐私模式
result.success(true); // 4. 返回成功
break;
2.2 三个关键操作
| 步骤 | 操作 | 作用 |
|---|---|---|
| 1 | this.secured = true |
标记保护已开启,后续窗口事件和生命周期回调会检查这个标志 |
| 2 | 解析 opacity | 可选参数,当前 Dart 层不传 |
| 3 | setPrivacyMode(true) |
调用系统 API 开启截屏防护 |
2.3 secured 标志的重要性
// 窗口事件回调中
if (this.secured && this.channel != null) {
this.channel.invokeMethod("lock", null);
}
// 生命周期回调中
if (this.secured && this.channel != null) {
this.channel.invokeMethod("lock", null);
}
this.secured 是所有事件回调的门控条件。如果不设置这个标志,即使用户没有调用 secure(),切后台也会触发锁定。
2.4 result.success 的时机
this.setPrivacyMode(true); // 异步操作
result.success(true); // 立即返回
setPrivacyMode 内部是异步的(setWindowPrivacyMode 返回 Promise),但 result.success 是立即调用的。这意味着 Dart 层收到 true 时,隐私模式可能还没真正生效。
📌 这是一个设计取舍:如果等 Promise resolve 后再返回,Dart 层会被阻塞。对于 secure_application 来说,快速返回比精确反馈更重要。
三、open 方法:关闭保护
3.1 执行流程
case "open":
this.secured = false;
this.setPrivacyMode(false);
result.success(true);
break;
3.2 与 secure 的对称性
| 操作 | secure | open |
|---|---|---|
| secured 标志 | true | false |
| 隐私模式 | 开启 | 关闭 |
| 返回值 | true | true |
open 是 secure 的逆操作,逻辑完全对称。
3.3 调用 open 后的效果
open() 调用后:
├── this.secured = false → 窗口事件和生命周期回调不再触发锁定
├── setPrivacyMode(false) → 系统允许截屏和录屏
└── Dart 层收到 true → controller.open() 完成
四、opacity 方法:参数更新
4.1 执行流程
case "opacity":
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");
}
result.success(true);
break;
4.2 三层防御
| 层级 | 防御 | 防止的问题 |
|---|---|---|
| 1 | try-catch | call.argument 抛出异常 |
| 2 | != null | 参数不存在 |
| 3 | != undefined | 参数类型不对 |
4.3 opacity 在原生端的用途
当前 OpenHarmony 端保存了 opacity 值但没有实际使用。这个值主要是为 iOS 端的原生模糊视图准备的。OpenHarmony 的模糊遮罩由 Flutter 层的 SecureGate 处理,不需要原生端参与。
// 保存了但没用到
private opacity: number = 0.2;
💡 保留这个逻辑是为了协议一致性——Dart 层不知道当前运行在哪个平台,它会向所有平台发送 opacity 参数。原生端接收并保存,即使不用也不报错。
五、lock / unlock:空实现的设计考量
5.1 代码
case "unlock":
result.success(true);
break;
case "lock":
result.success(true);
break;
5.2 为什么是空实现
Dart 层的 SecureApplicationNative.lock() 和 SecureApplicationNative.unlock() 会调用这两个方法。但在 OpenHarmony 端,锁定和解锁的原生操作已经在其他地方处理了:
| 操作 | 在哪里处理 | 为什么不在 lock/unlock 中处理 |
|---|---|---|
| 开启隐私模式 | secure 方法 | 隐私模式跟随 secure/open,不跟随 lock/unlock |
| 窗口事件监听 | registerWindowEventCallback | 已经在 onAttachedToEngine 中注册 |
| 生命周期回调 | registerLifecycleCallback | 已经在 onAttachedToEngine 中注册 |
5.3 lock/unlock 在其他平台的作用
| 平台 | lock 的原生行为 | unlock 的原生行为 |
|---|---|---|
| Android | 空实现 | 空实现 |
| iOS | 添加模糊视图 | 移除模糊视图 |
| OpenHarmony | 空实现 | 空实现 |
| Web | 空实现 | 空实现 |
只有 iOS 在 lock/unlock 时有原生操作(添加/移除 UIVisualEffectView)。其他平台都是空实现。
5.4 为什么不直接返回 notImplemented
// 当前做法:返回 true
case "lock":
result.success(true);
break;
// 替代做法:返回 notImplemented
case "lock":
result.notImplemented();
break;
如果返回 notImplemented,Dart 层会抛出 MissingPluginException。虽然 Dart 层的调用代码没有 await 这个 Future,但异常仍然会出现在控制台中,造成不必要的噪音。
六、default 分支
6.1 代码
default:
result.success(true);
break;
6.2 容错 vs 严格
| 策略 | default 行为 | 优点 | 缺点 |
|---|---|---|---|
| 容错 | result.success(true) | 不会因未知方法崩溃 | 拼写错误不易发现 |
| 严格 | result.notImplemented() | 拼写错误立即暴露 | 可能导致异常 |
secure_application 选择了容错策略。对于安全类插件来说,稳定性比严格性更重要——宁可某个方法静默失败,也不要让 App 因为一个未知方法而崩溃。
七、方法调用的完整生命周期
7.1 一次 secure() 调用的完整链路
1. 用户代码:controller.secure()
2. Controller:SecureApplicationNative.secure()
3. Native类:_channel.invokeMethod('secure')
4. MethodChannel:序列化 → 平台通道 → 反序列化
5. onMethodCall:case "secure"
6. 原生逻辑:this.secured = true; setPrivacyMode(true)
7. 系统API:win.setWindowPrivacyMode(true)
8. 返回:result.success(true)
9. MethodChannel:序列化 → 平台通道 → 反序列化
10. Dart Future:resolve(true)
7.2 耗时分析
| 步骤 | 耗时 | 说明 |
|---|---|---|
| 1-4 | <1ms | Dart 层调用 + 序列化 |
| 5-6 | <1ms | 方法分发 + 标志位设置 |
| 7 | 5-20ms | 系统 API 异步调用 |
| 8-10 | <1ms | 返回 + 反序列化 |
| 总计 | <25ms | 用户无感知 |
📌 注意:result.success 在步骤7之前就返回了,所以 Dart 层感知到的延迟只有步骤1-6和8-10,大约2ms。系统 API 的20ms 延迟是在后台异步完成的。
总结
本文详细分析了 onMethodCall 的每个分支:
- secure:设置标志位 + 解析可选参数 + 开启隐私模式
- open:清除标志位 + 关闭隐私模式
- opacity:三层防御解析参数,保存但不使用
- lock/unlock:空实现,原生操作在其他地方处理
- default:容错返回 true,不抛异常
下一篇我们讲资源释放与回调注销——插件生命周期结束时的清理工作。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- MethodCall 文档
- MethodResult 文档
- secure_application OpenHarmony 源码
- setWindowPrivacyMode API
- Flutter Platform Channels
- ArkTS switch-case 语法
- MissingPluginException
- 开源鸿蒙跨平台社区

方法调用分发流程示意图
更多推荐


所有评论(0)