Flutter三方库适配OpenHarmony【secure_application】— 调试与问题排查实战

前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

开发插件的过程中,最头疼的不是写代码,而是出了问题不知道哪里错了。MethodChannel 通信跨越了 Dart 和 ArkTS 两个运行时,一个方法调用可能在任何一层出问题。这篇分享我在适配 secure_application 过程中积累的调试技巧和排查经验。

一、日志规范与 TAG 管理

1.1 TAG 定义

typescript 复制代码
const TAG = "SecureApplicationPlugin";

所有日志都带 TAG 前缀,方便在海量日志中过滤。

1.2 Log 级别使用规范

typescript 复制代码
// 信息日志:正常流程的关键节点
Log.i(TAG, "Got main window successfully");
Log.i(TAG, "Window privacy mode set to: " + isPrivacy);
Log.i(TAG, "Lifecycle callback registered");

// 错误日志:异常和失败
Log.e(TAG, "Failed to get main window: " + JSON.stringify(err));
Log.e(TAG, "Failed to set window privacy mode: " + JSON.stringify(err));
级别 方法 用途 示例
Info Log.i 正常流程节点 窗口获取成功、隐私模式设置成功
Error Log.e 异常和失败 API 调用失败、参数解析错误
Debug Log.d 详细调试信息 方法调用参数、状态变化
Warn Log.w 潜在问题 空值降级、重试操作

1.3 关键日志点

typescript 复制代码
// 插件生命周期
Log.i(TAG, "Plugin attached to engine");
Log.i(TAG, "Plugin detached from engine");

// 窗口管理
Log.i(TAG, "Got main window successfully");
Log.i(TAG, "Window event callback registered");
Log.i(TAG, "Window event callback unregistered");

// 隐私模式
Log.i(TAG, "Window privacy mode set to: " + isPrivacy);

// 生命周期回调
Log.i(TAG, "Application came to foreground");
Log.i(TAG, "Application went to background");
Log.i(TAG, "Window became inactive");

// 方法调用
Log.i(TAG, "onMethodCall: " + call.method);

📌 建议:在开发阶段多加日志,发布前可以移除 Debug 级别的日志,保留 Info 和 Error 级别。

二、DevEco Studio 日志查看

2.1 HiLog 面板

DevEco Studio 内置了 HiLog 面板,类似 Android Studio 的 Logcat:

  1. 打开 DevEco Studio
  2. 底部工具栏 → HiLog
  3. 在搜索框输入 SecureApplicationPlugin
  4. 选择日志级别过滤

2.2 过滤技巧

过滤方式 语法 示例
TAG 过滤 直接输入 TAG SecureApplicationPlugin
级别过滤 选择下拉菜单 Info / Error / Debug
关键词过滤 输入关键词 privacy mode
正则过滤 使用正则表达式 Window.*failed

2.3 常用过滤组合

复制代码
# 只看 secure_application 的日志
TAG: SecureApplicationPlugin

# 只看错误
TAG: SecureApplicationPlugin + Level: Error

# 看 MethodChannel 通信
TAG: SecureApplicationPlugin + 关键词: onMethodCall

# 看窗口事件
TAG: SecureApplicationPlugin + 关键词: Window

三、hdc hilog 命令行日志

3.1 基本用法

bash 复制代码
# 实时查看所有日志
hdc hilog

# 过滤 TAG
hdc hilog | grep SecureApplicationPlugin

# 只看错误
hdc hilog | grep "SecureApplicationPlugin" | grep -i "error\|fail"

# 保存到文件
hdc hilog | grep SecureApplicationPlugin > secure_app_log.txt

3.2 高级过滤

bash 复制代码
# 同时看 Flutter 和插件日志
hdc hilog | grep -E "SecureApplicationPlugin|flutter"

# 看 MethodChannel 通信(两端)
hdc hilog | grep -E "SecureApplicationPlugin|MethodChannel"

# 带时间戳过滤
hdc hilog -T "2024-01-15 10:00:00" | grep SecureApplicationPlugin

3.3 清除日志缓冲

bash 复制代码
# 清除旧日志,从头开始
hdc hilog -r
hdc hilog | grep SecureApplicationPlugin

四、MethodChannel 通信调试

4.1 在原生端添加方法调用日志

typescript 复制代码
onMethodCall(call: MethodCall, result: MethodResult): void {
  Log.i(TAG, "onMethodCall: method=" + call.method + ", args=" + JSON.stringify(call.args));

  switch (call.method) {
    case "secure":
      Log.i(TAG, "Processing secure command");
      // ...
      Log.i(TAG, "Secure command completed");
      break;
    // ...
  }
}

4.2 在 Dart 端添加调用日志

dart 复制代码
class SecureApplicationNative {
  static Future secure() {
    print('[SecureApp] Dart → Native: secure');
    return _channel.invokeMethod('secure');
  }

  static Future open() {
    print('[SecureApp] Dart → Native: open');
    return _channel.invokeMethod('open');
  }
}

4.3 通信断点调试

在 DevEco Studio 中可以在 ArkTS 代码中设置断点:

  1. 打开 SecureApplicationPlugin.ets
  2. 在 onMethodCall 的 switch 语句处设置断点
  3. 从 Dart 层触发方法调用
  4. 断点命中后检查 call.method 和 call.args

⚠️ 注意:ArkTS 断点调试和 Flutter 的 Dart 断点调试不能同时使用。需要分别调试。

五、常见问题排查

5.1 问题一:隐私模式不生效

症状:调用 secure() 后截屏仍然正常

排查步骤:

bash 复制代码
# 1. 检查方法是否被调用
hdc hilog | grep "onMethodCall.*secure"

# 2. 检查隐私模式是否设置成功
hdc hilog | grep "Window privacy mode"

# 3. 检查窗口是否获取成功
hdc hilog | grep "Got main window"

# 4. 检查是否有错误
hdc hilog | grep "SecureApplicationPlugin" | grep -i "fail\|error"
日志结果 问题定位 解决方案
没有 onMethodCall 日志 MethodChannel 未连接 检查通道名称是否一致
有 onMethodCall 但没有 privacy mode setPrivacyMode 未执行 检查 mainWindow 是否为 null
有 privacy mode 但有 error API 调用失败 检查错误码
所有日志正常 可能是设备不支持 检查 API 版本

5.2 问题二:锁定不触发

症状:切后台后没有显示模糊遮罩

排查步骤:

bash 复制代码
# 1. 检查窗口事件是否触发
hdc hilog | grep "Window became inactive"

# 2. 检查生命周期回调是否触发
hdc hilog | grep "Application went to background"

# 3. 检查 secured 状态
hdc hilog | grep "Processing secure command"
日志结果 问题定位 解决方案
没有 inactive 日志 窗口事件未注册 检查 registerWindowEventCallback
有 inactive 但没有 lock this.secured 为 false 确认调用了 secure()
有 lock 通知 Dart 层问题 检查 Dart 层的 lockIfSecured

5.3 问题三:遮罩不显示

症状:锁定状态但看不到模糊遮罩

排查步骤:

dart 复制代码
// 在 SecureGate 中添加调试日志
void _sercureNotified() {
  print('[SecureGate] locked=${_secureApplicationController!.locked}');
  if (_lock == false && _secureApplicationController!.locked == true) {
    print('[SecureGate] Showing blur overlay');
    _lock = true;
    _gateVisibility.value = 1;
  }
}
问题 原因 解决
SecureGate 没有被包裹 Widget 树结构问题 确认 SecureGate 在 SecureApplication 内部
blurr=0 模糊强度为0 调高 blurr 值
opacity=0 完全透明 调高 opacity 值
Controller 未连接 Provider 查找失败 确认 SecureApplicationProvider 在上层

5.4 问题四:热重载后行为异常

症状:热重载后回调重复触发或不触发

排查步骤:

bash 复制代码
# 检查是否有重复的注册日志
hdc hilog | grep "callback registered"

# 预期:每次热重载后只有一组注册日志
# 异常:多组注册日志(说明旧回调没有注销)

解决 :确认 onDetachedFromEngine 正确注销了所有回调。

六、调试工具推荐

6.1 Flutter DevTools

bash 复制代码
# 启动 DevTools
flutter run -d ohos_device --observatory-port=8888
# 在浏览器打开 DevTools URL
功能 用途
Widget Inspector 检查 SecureGate 的 Widget 树
Timeline 查看动画帧率
Memory 检查内存泄漏
Logging 查看 Dart 层日志

6.2 DevEco Studio Profiler

功能 用途
CPU Profiler 检查原生端 CPU 使用
Memory Profiler 检查原生端内存
HiLog 查看系统日志

6.3 自定义调试工具

dart 复制代码
// 添加一个调试面板
class SecureDebugPanel extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final controller = SecureApplicationProvider.of(context);
    return Column(
      children: [
        Text('secured: ${controller?.secured}'),
        Text('locked: ${controller?.locked}'),
        Text('paused: ${controller?.paused}'),
        Text('authenticated: ${controller?.authenticated}'),
      ],
    );
  }
}

七、排查检查清单

7.1 通用检查清单

  • 通道名称 "secure_application" 两端一致
  • pubspec.yaml 中 ohos 平台已声明
  • oh-package.json5 中 name 正确
  • index.ets 导出路径正确
  • 设备 API 版本 >= 20
  • hdc 连接正常

7.2 隐私模式检查清单

  • getMainWindow 成功(日志确认)
  • setWindowPrivacyMode 成功(日志确认)
  • secure() 被调用(日志确认)
  • 无错误日志

7.3 锁定功能检查清单

  • 窗口事件回调已注册(日志确认)
  • 生命周期回调已注册(日志确认)
  • secured 状态为 true
  • channel 不为 null
  • Dart 层收到 lock 通知

总结

本文分享了 secure_application 适配过程中的调试技巧:

  1. 日志规范:TAG 统一、级别分明、关键节点全覆盖
  2. HiLog 过滤:DevEco Studio 面板 + hdc 命令行
  3. MethodChannel 调试:两端加日志、断点调试
  4. 四个常见问题:隐私模式不生效、锁定不触发、遮罩不显示、热重载异常
  5. 排查检查清单:通用、隐私模式、锁定功能三个维度

下一篇我们讲性能影响与优化策略------BackdropFilter 的 GPU 开销和窗口事件的频率控制。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

DevEco Studio HiLog 日志面板

相关推荐
梦想不只是梦与想13 小时前
HarmonyOS应用分层架构设计
harmonyos·分层架构·一次开发,多端部署
MardaWang15 小时前
当滚动逃离了框架 ——HarmonyOS Web 与原生混排滚动的冲突本质与解法
harmonyos·arkts·鸿蒙·deveco studio
tsqtsqtsq030916 小时前
DevEco Studio 介绍
harmonyos
传奇开心果编程19 小时前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
HwJack2019 小时前
【共创稿事节】HarmonyOS 7文旅展陈展厅大空间 3DGS 重建的分块策略与拼接踩坑
3d·华为·harmonyos
m0_7381858221 小时前
Flutter 鸿蒙化实战:media_info 适配 OpenHarmony,媒体信息与缩略图
flutter·华为·harmonyos·鸿蒙·媒体
m0_738185821 天前
Flutter 鸿蒙化实战:just_audio 适配 OpenHarmony,功能强大的播放器
flutter·华为·harmonyos·鸿蒙
翼辉cto1 天前
Kotlin Multiplatform 三方库 SQLDelight 的 OpenHarmony 鸿蒙化适配实战
开发语言·kotlin·harmonyos
SuperHeroWu71 天前
TraeCode 国内版接入 DevEco CLI:用官方知识开发鸿蒙应用
ai编程·harmonyos·知识库·trae·aicoding·skills·deveco cli