适配仓库: 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
当前远程 HEADa1ef8ef71241e5684f4412b8130f6053227d0804
新增 OHOS 能力读取 STARTUP uptime,返回运行时长并估算设备启动时刻
真机结论运行时长递增、别名一致性及独立系统 API 对照两轮通过

二、验证环境

项目实测值
Flutter OH3.41.10-ohos-1.0.1
Dart3.11.5
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 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,原生方法只有 getPlatformVersiongetRunTimeMsgetBootTimeDurationDateTimegetBootTimeMs 别名继续由 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=33974055durationMs=33974057,等待 250 ms 后增量为 255 ms;第二轮对应为 3397585733975858 和 253 ms。数值为非负安全整数,Duration 与毫秒入口也保持同一单位。

两轮中,getBootTime()getBootTimeMilliseconds()getBootTimeMs() 的毫秒值都在 17890636167451789063616746 之间,与宿主直接读取的 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

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐