React Native for OpenHarmony 三方库 react-native-app-info 0.0.6 适配实战:从系统读取应用元数据
React Native for OpenHarmony 三方库 react-native-app-info 0.0.6 适配实战:从系统读取应用元数据
这篇文章面向第一次接触 React Native for OpenHarmony 的读者。我们不只展示“能跑起来”的结果,而是把从上游代码、鸿蒙原生实现、HAR 打包、宿主接入到真机验收的过程完整走一遍。
适配仓库: oh-react-native/react-native-app-info
交付分支: main
适配 TAG: 0.0.6-ohos-1.0.1
受测提交: 1497a2a506b6af26021f5b48a17dd05b5f52d0a0
配套源码: react-native-app-info
一、这个库解决什么问题
在业务应用里,“当前应用叫什么、版本是多少、Bundle ID 是什么”看起来像简单字符串,实际上都属于宿主系统的应用包信息。例如关于页要显示版本,问题反馈页要附带应用标识,埋点要区分不同构建版本,升级提示也需要比较 versionCode 和 versionName。react-native-app-info 把这些平台差异藏在一个 JavaScript API 后面:Android 从 PackageManager 读,iOS 从 NSBundle 读,业务代码只关心 getInfoVersion、getInfoShortVersion、getInfoBundleIdentifier、getInfoName 和 getInfoDisplayName。
OpenHarmony 没有 Android 的 PackageManager 类,也不能直接读取 iOS 的 Info.plist,所以“把 JS 文件复制到鸿蒙目录”是不够的。本次适配的目标是让同一套 JS 调用真正进入 RNOH 的 TurboModule,再由 ArkTS 调用 OpenHarmony 的 bundleManager。适配前已经在 oh-react-native 组织、CPF-RN 组织 和活动中心记录中按完整包名、去 scope 名称及 rntpc 前缀去重,没有发现已有同上游的有效鸿蒙实现。

图 1:精简 tgz 安装到独立宿主后,签名 HAP 在 OpenHarmony 真机离线启动。页面显示的不是预置文本,而是本库返回的宿主信息。

图 2:五个 getter 都返回成功。version、shortVersion 和 Bundle ID 均与受测宿主的系统信息逐项核对。
二、环境和上游基线
本次只记录实际验证所用环境,不把“安装环境”当成文章主题。React Native 为 0.84.1,React 为 19.2.3,RNOH 为 0.84.3,DevEco Studio 为 26.0.0 Release,测试 ROM 为 OpenHarmony-7.0.0.105。上游版本为 0.0.6,适配提交和 TAG 已在文首链接锁定。这样做的好处是读者能区分“文章描述的版本”和“自己电脑上后来安装的版本”,也能在仓库提交和证据之间建立对应关系。
本库是以 JS 为入口、带原生能力的 TurboModule,并非纯 JS 组件。交付目录保留 index.js、index.harmony.js、TypeScript Spec、harmony/react_native_app_info.har、ArkTS 实现、C++ Package、CMake、测试、双语 README、许可证和 spec.json。node_modules、oh_modules、build、.hvigor、签名文件和完整宿主没有上传,它们属于本地验证材料。
三、从 JS 到鸿蒙系统的调用链
整条链可以画成:
业务页面
-> react-native-app-info 的 index.harmony.js
-> NativeAppInfo.ts TurboModule Spec
-> RNOH C++ Package 方法登记
-> ArkTS AppInfoTurboModule
-> bundleManager.getBundleInfoForSelfSync
原库的五个读取方法需要逐个定义语义。version 是构建版本号字符串,shortVersion 是用户可见的版本名称,bundleIdentifier 是当前宿主包名,name 是系统内部应用名,displayName 是面向用户的显示名。适配时不能把所有字段都指向同一个 label,否则在测试值恰好相同的时候会掩盖映射错误。
ArkTS 原生入口位于 harmony/app_info/index.ets,使用 getBundleInfoForSelfSync,并传入 GET_BUNDLE_INFO_WITH_APPLICATION 标志。displayName 先检查 labelId,再通过 resourceManager.getStringSync 解析资源;只有没有资源 ID 时才退回 label。这样既支持 AppScope 中的资源化名称,也不会把资源引用字符串误当成最终显示文本。C++ 层和 Package 工厂的作用是把模块注册给 RNOH,真正查询系统数据的代码仍在 ArkTS。
index.harmony.js 负责保持原库的公开对象形状。package.json 增加 react-native: ./index,让 Metro 在 HarmonyOS 平台解析到鸿蒙入口;只新增一个文件而没有检查 source map,很容易出现“源码看起来适配了,但宿主仍加载上游 index.js”的假成功。
网络活动指示器是一个必须主动说明的差异。iOS 有系统指示器,OpenHarmony 没有可对应的公共能力,因此 setNetworkActivityIndicatorVisible 在鸿蒙侧保留兼容空实现,其他平台仍使用上游行为。空实现只表示“不破坏调用”,不代表鸿蒙支持这个系统视觉效果。
四、实际修改了哪些文件
- 在根目录保留原入口和类型文件,并新增 index.harmony.js,让 Metro 选择鸿蒙版本。
- 在 src 中保留 NativeAppInfo.ts,声明五个同步 getter 以及兼容方法,名称、返回值和异常形态与上游一致。
- 在 harmony/app_info/ 中加入 oh-package.json5、build-profile.json5、hvigorfile.ts、module.json5、ArkTS Package 和 AppInfoTurboModule.ts。
- 在 harmony/app_info/src/main/cpp/ 中保留 CMake 和 Codegen 生成的 Package/方法登记,确保 C++ 的模块名 RNAppInfo 与 JS Spec、ArkTS 工厂一致。
- 在 harmony/ 根目录保留 react_native_app_info.har。HAR 是消费方通过 ohpm 接入的分发产物,不能因为目录看起来像构建缓存就删除。
读者如果要改这个库,建议先只改一个层次再验证:JS 类型变化先跑类型检查;Spec 或方法登记变化要重新生成并构建 HAR;ArkTS 系统查询变化必须重新构建 HAP 并上真机。不要用旧截图证明修改后的源码仍然正确。
五、从实际 tgz 接入一个干净宿主
验证使用一个独立的 RNOH 宿主,实际安装的是与文首 TAG 对应的 react-native-app-info-0.0.6.tgz。读者只需要把 tgz 下载到自己的工程目录,再按下面顺序执行;文章不依赖作者电脑上的目录。
export RNOH_HOST="$HOME/rnoh-qa"
export EVIDENCE_DIR="$RNOH_HOST/evidence/react-native-app-info"
mkdir -p "$EVIDENCE_DIR"
cd "$RNOH_HOST"
npm install "$HOME/Downloads/react-native-app-info-0.0.6.tgz" --save-exact
./node_modules/.bin/react-native link-harmony
cd harmony
ohpm install --all
cd ..
./node_modules/.bin/react-native bundle-harmony --dev false --sourcemap-output "$EVIDENCE_DIR/bundle.map"
hvigorw assembleHap --mode module -p product=default --no-daemon
这里有三个容易混淆的概念。npm install 安装的是 JS 和 HAR 的消费包;link-harmony 生成宿主的自动链接关系;bundle-harmony 把 JS 资源放进 HAP。–dev false 只代表 bundle 的开发标志,不代表 HAP 一定是 release,本次受测的是签名 debug HAP。构建后要看 source map,确认来源是 node_modules 中安装的 tgz,而不是上游缓存目录。
真机安装和截图可以使用设备序列号明确指定目标,避免多台设备时装错包:
hdc list targets
export DEVICE_ID="$(hdc list targets | awk 'NF {print $1; exit}')"
hdc -t "$DEVICE_ID" install "$RNOH_HOST/output/tested.hap"
hdc -t "$DEVICE_ID" shell power-shell wakeup
hdc -t "$DEVICE_ID" shell power-shell timeout -o 2147483647
hdc -t "$DEVICE_ID" shell aa start -a EntryAbility -b com.example.rnqa
hdc -t "$DEVICE_ID" shell uitest screenCap -p /data/local/tmp/app-info.png
hdc -t "$DEVICE_ID" file recv /data/local/tmp/app-info.png "$EVIDENCE_DIR/app-info.png"
常亮设置只为本轮取证服务,结束后应恢复设备原来的超时值;不要把 2147483647 当作应用必须设置的用户配置。
六、业务侧如何调用
页面可以从一个最小的按钮开始。下面的代码保留上游 API,不需要业务方直接接触 ArkTS:
import AppInfo from 'react-native-app-info';
export async function readAppInfo() {
const data = {
version: AppInfo.getInfoVersion(),
shortVersion: AppInfo.getInfoShortVersion(),
bundleId: AppInfo.getInfoBundleIdentifier(),
name: AppInfo.getInfoName(),
displayName: AppInfo.getInfoDisplayName(),
};
return data;
}
同步 getter 的含义是“模块初始化阶段已经完成系统查询,调用时读取缓存”,不是每次调用都再次查询系统。真机上做了 4 轮、每轮 100 次的重复读取,确认五个字段稳定;这 400 轮是缓存一致性检查,不是 400 次系统查询,也不是性能基准。
七、真机验证过程
首先使用设备工具确认目标设备,然后安装最终 HAP。业务页面启动后先读取五个 getter,再把独立系统探针的结果写入页面。随后反复读取,并让宿主经历一次外部系统页面往返,再回到 RN 页面,最后强停应用并启动第二个进程,确认 HAP 内置资源 bundle 可以冷启动。下面三张设置页截图属于宿主前后台往返检查,不是 app-info 提供了“打开设置页”这个功能;该跳转能力属于另一个独立库。

图 3:从业务页面打开当前应用的系统设置详情页,系统显示的目标包与宿主 Bundle ID 一致。

图 4:重复进入设置页,名称和版本仍来自同一受测宿主,未把旧应用缓存误当成库返回值。

图 5:第三次往返后页面仍能回到 RN 宿主,说明跳转期间没有破坏模块状态。

图 6:返回后再次读取五个 getter,值与冷启动时一致。

图 7:强停后以不同进程再次启动,仍能显示同一组真实元数据,证明不是 Metro 临时下发。
本轮受测 HAP 的 SHA-256 为 8cb4f808908eb7c13117e0b3f6310febe527ebbc8f63bfee952ecd055668838d。读者复现时应以自己构建的 HAP 哈希和设备截图为准;上面的图片只展示发布文章所需的真机结果,不把作者本地日志目录当成公开链接。
八、遇到的问题、限制和结论
最容易出现的错误是把显示名写成资源引用、把 version 和 shortVersion 混用,或者在 package.json 没有配置平台入口时误以为 index.harmony.js 会自动生效。本次逐项修正并通过真机字段区分验证。另一个限制是 setNetworkActivityIndicatorVisible 只能兼容调用,不能在鸿蒙上显示 iOS 风格指示器。
本次只在一台 OpenHarmony-7.0.0.105 手机验证,没有覆盖平板、2in1、多模块应用、不同语言资源和其他 ROM;没有验证设备断网,资源 bundle 冷启动也不等于断网测试。构建通过只能说明工程可打包,只有安装最终 HAP、读取系统真值、重复调用和冷启动都通过,才可以写成“适配完成”。
九、参考链接
- 上游 npm 包 react-native-app-info
- 适配仓库首页
- 适配仓库 main 分支
- 受测 TAG 0.0.6-ohos-1.0.1
- HarmonyOS 开发者文档
- OpenHarmony bundleManager API
欢迎加入 RN for OpenHarmony 社区。
更多推荐



所有评论(0)