Flutter 鸿蒙插件适配实战:用 boot_time_plugin 1.0.0 读取启动时间与运行时长
适配仓库: https://atomgit.com/oh-flutter/boot_time_plugin
适配 TAG: 尚未发布,当前请锁定受测提交
受测提交:
a1ef8ef71241e5684f4412b8130f6053227d0804
一、最终效果与适配目标
崩溃诊断、稳定性统计和“设备多久没重启”场景常需要系统运行时长。boot_time_plugin 1.0.0 对外提供运行毫秒、Duration、启动时间毫秒和 DateTime,但原版没有 OHOS 支持。
这两个概念不能混淆:uptime 是自启动以来累计的时长;启动时刻是“当前墙钟减去 uptime”得到的估计。用户手工校时或系统自动校时后,估计时刻可能改变,即使设备没有重启。因此它不能作为稳定设备标识、防篡改时钟或持久历史事件。

图 1:真机宿主显示 runtime、Duration、启动估计与独立对照。
| 验证点 | 实测结果 | 证据 |
|---|---|---|
| 运行时长 | 两轮返回非负安全整数,等待 250 ms 后按预期递增 | 图 1、图 6 |
| 启动时刻别名 | 三个入口毫秒值一致 | 图 6 |
| 独立系统对照 | 与宿主 wallMs - STARTUP 的差值小于 2 ms | 图 6 |
| 自动化与构建 | 34 项 Dart/Widget/ArkTS 功能测试及 HAP 构建通过 | 图 4、图 5 |
| 验证边界 | 未完成长时间深睡/唤醒实验,不承诺所有平台的休眠口径相同 | 真机说明 |
成果速览
| 项目 | 内容 |
|---|---|
| 上游基线 | 1.0.0 对应提交 704960c7063fd0ff9248cfd4093bb62b8ea00933,MIT |
| 适配分支 | feat/ohos_boot_time_plugin_1.0.0 |
| 适配 TAG | 尚未发布 |
| 真机受测提交 | a1ef8ef71241e5684f4412b8130f6053227d0804 |
| 当前远程 HEAD | a1ef8ef71241e5684f4412b8130f6053227d0804 |
| 新增 OHOS 能力 | 读取 STARTUP uptime,返回运行时长并估算设备启动时刻 |
| 真机结论 | 运行时长递增、别名一致性及独立系统 API 对照两轮通过 |
二、验证环境
| 项目 | 实测值 |
|---|---|
| Flutter OH | 3.41.10-ohos-1.0.1 |
| Dart | 3.11.5 |
| DevEco Studio | 26.0.0 Release |
| HarmonyOS SDK | API 26;示例兼容 API 18,计时接口 API 10+ |
| 设备 | CHZ-AL00,HarmonyOS 7.0.0.105(SP10C00E105R2P4) |
| 插件 | boot_time_plugin 1.0.0 |
环境搭建参考 Flutter OH 指南。截至 2026 年 9 月 12 日,版本号最大的 Flutter OH 标签是预览版 3.44.9+ohos-0.0.1-canary1,最新正式稳定标签仍是本文完成构建和真机回归的 3.41.10-ohos-1.0.1。
三、版本来源与 AtomGit 分支
最新发布版为 1.0.0,本次上游基线提交 704960c7063fd0ff9248cfd4093bb62b8ea00933。逐文件比对后,发布包和上游主要差异只是换行,唯一内容差异是 iOS 注释,没有未发布功能漂移。MIT 许可证及 Git 历史完整保留。适配前实时组织排重未发现同包交付。
git clone https://atomgit.com/oh-flutter/boot_time_plugin.git
cd boot_time_plugin
git switch feat/ohos_boot_time_plugin_1.0.0
git branch --show-current
从基线复现:
git switch -c feat/ohos_boot_time_plugin_1.0.0 704960c7063fd0ff9248cfd4093bb62b8ea00933
flutter create --template=plugin --platforms=ohos --no-pub .
生成后的模板方法要替换成原通道和时间 API。图 2 汇总了实际 AtomGit origin、适配分支和 HEAD,可核对仓库来源与当前分支状态。

图 2:AtomGit 来源、适配分支与 HEAD。
四、保留全部公开别名
final runtimeMs = await BootTimePlugin.getRunTimeMs();
final runtime = await BootTimePlugin.getRunTime();
final bootMs = await BootTimePlugin.getBootTimeMilliseconds();
final bootAlias = await BootTimePlugin.getBootTimeMs();
final bootTime = await BootTimePlugin.getBootTime();
内部通道为 boot_time_plugin,原生方法只有 getPlatformVersion、getRunTimeMs 和 getBootTime。Duration、DateTime 与 getBootTimeMs 别名继续由 Dart 转换,不在 ArkTS 重复实现。
五、OHOS 时间语义
pubspec.yaml 注册 BootTimePlugin。运行时长使用:
const epoch = call.method === 'getBootTime'
? systemDateTime.getTime(false)
: 0;
const uptime = systemDateTime.getUptime(
systemDateTime.TimeType.STARTUP,
false,
);
const value = call.method === 'getBootTime' ? epoch - uptime : uptime;
TimeType.STARTUP 包含深度休眠,与上游 Android 的 elapsedRealtime() 方向一致。上游 iOS 的 systemUptime 不包含休眠,所以不能宣称三平台深睡语义完全相同。
实现按 Android 顺序先读墙钟、再读 uptime,但它们仍不是原子快照。每次调用重新读取,不缓存;短时间重复调用有毫秒差异是合理的。uptime 必须是非负安全整数,启动估计还必须落在 Dart DateTime 的可表示范围。无效值为 NO_TIME_DATA,系统异常为 TIME_QUERY_FAILED,Engine 未绑定为 UNAVAILABLE。

图 3:systemDateTime STARTUP uptime 与 wall clock 相减的启动时刻估计。
六、交付内容
本分支没有改原 lib/、Android 或 iOS 运行时代码,保留 MIT LICENSE 和历史;新增 OHOS HAR、example/ohos/、双语适配文档、Dart/Widget 测试、生产 ArkTS 测试及设备入口。示例提供刷新、错误重试和窄屏滚动。
签名材料、SDK 路径、Node 依赖、生成文件和构建产物不入库。系统计时 API 不要求额外权限。
七、自动化和构建结果
flutter pub get
flutter analyze
flutter test
npm install --prefix ohos/test --no-save --no-package-lock typescript@5.9.3
node --test ohos/test/boot_time_plugin.test.cjs
cd example
flutter test
flutter build hap --debug --no-codesign
17 项 Dart、2 项 widget、15 项生产 ArkTS 功能测试通过,共 34 项;另有 1 项重复响应夹具自检,不计入功能数。静态分析和无签名 debug HAP 通过。测试覆盖 STARTUP 枚举、毫秒参数、int32 以上数值、负启动估计、DateTime 边界、系统异常、新鲜读取、校时变化、未知方法和解绑重绑。
最终代码提交为 a1ef8ef71241e5684f4412b8130f6053227d0804。

图 4:Flutter 复跑与 34 项 Dart/ArkTS/Widget 用例统计。

图 5:HAP 摘要与真机宿主锁定的 AtomGit SHA。
八、Demo 与真机验收
dependencies:
boot_time_plugin:
git:
url: https://atomgit.com/oh-flutter/boot_time_plugin.git
ref: a1ef8ef71241e5684f4412b8130f6053227d0804
执行 flutter pub get 后应核对 pubspec.lock 中的 resolved-ref。当前尚无 OHOS 适配 TAG,因此示例锁定到完成上述自动化和真机验收的完整提交。
隔离宿主通过远程 Git 固定到 a1ef8ef71241e5684f4412b8130f6053227d0804,完成分析、签名 HAP 构建和覆盖安装。2026 年 9 月 11 日在 SP10 真机连续运行两轮。第一轮 runtimeMs=33974055、durationMs=33974057,等待 250 ms 后增量为 255 ms;第二轮对应为 33975857、33975858 和 253 ms。数值为非负安全整数,Duration 与毫秒入口也保持同一单位。
两轮中,getBootTime()、getBootTimeMilliseconds() 和 getBootTimeMs() 的毫秒值都在 1789063616745 到 1789063616746 之间,与宿主直接读取的 wallMs - STARTUP 一致,并远小于设定的 2 秒采样容差;平台版本返回 OpenHarmony-7.0.0.105,未知方法为 notImplemented。/proc/uptime 仍然因权限被拒绝,本次没有提权绕过;短时前台递增也不能替代受控的深睡/唤醒实验。

图 6:两轮 uptime 进位、别名一致性与 wallMs - STARTUP 独立对照。
应用内多状态补拍

图 7:首次页面采样展示系统版本、估算启动时刻、运行时长及两个启动 epoch 入口。

图 8:刷新后运行时长继续增加,启动时刻与两个 epoch 别名保持一致。
九、提交与远端核验
git status --short
git add pubspec.yaml ohos example test README.OpenHarmony.md README.OpenHarmony_CN.md
git commit -m "feat(ohos): add boot_time_plugin OpenHarmony support"
git push -u origin feat/ohos_boot_time_plugin_1.0.0
仓库公开,适配分支为默认分支。2026 年 9 月 12 日匿名核对 HEAD 为 a1ef8ef71241e5684f4412b8130f6053227d0804,与真机受测提交一致。
十、FAQ
Q1:启动时间多次读取为什么会变化
- 现象: 两次估计相差少量毫秒,校时后差异更大。
- 原因: 它由两次非原子系统读取相减得到,并非持久启动事件。
- 解决方法: 使用合理容差;不要把结果当成安全标识。
- 验证结果: 自动化覆盖新鲜读取和墙钟变化;真机三个别名与独立参考的差值小于 2 毫秒。
Q2:uptime 是否包含应用后台时间
- 现象: 开发者把它误认为 Flutter 进程运行时长。
- 原因:
STARTUP表示设备自启动以来的系统时长,包含深睡语义,不是应用生命周期计时。 - 解决方法: 应用自身会话时长另用单调计时器记录。
- 验证结果: 枚举和参数已由生产源码测试确认,真实深睡尚未验收。
Q3:为什么不用 /proc/uptime 对照
- 现象: 真机命令返回 Permission denied。
- 原因: 普通应用/调试 shell 没有该文件读取权限。
- 解决方法: 使用公开系统时间 API 作为独立基线,不提权绕过系统限制。
- 验证结果: 保留
/proc失败记录,并已用宿主公开系统 API 完成两轮对照。
十一、总结
boot_time_plugin 的 OHOS 适配保留了全部公开入口,用 STARTUP uptime 提供运行时长,并用当前墙钟减 uptime 估计启动时刻。34 项功能测试、静态分析和两类 HAP 构建已经通过;两轮真机公共 API 也覆盖了 uptime 前进、单位、启动别名和独立系统对照。未覆盖的是长时深睡语义,这个限制不能用短时前台测试消除。
十二、参考链接
欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter
更多推荐




所有评论(0)