React Native for OpenHarmony 实战:三方库 expo-keep-awake 的鸿蒙化适配指南
刷文档、看视频、导航的时候屏幕自动熄灭,是最扫兴的一件事。expo-keep-awake 就是解决这个的库——让应用在前台时保持屏幕常亮。它是 Expo 体系里的基础库,很多上层库(视频播放器、阅读器、地图导航)都会间接依赖它。
这个库在鸿蒙上没有官方实现,所以我做了一版适配。本文把整条链路写清楚:从上游同步、鸿蒙实现怎么写、到接入宿主并跑通。
环境准备:本文不重复环境搭建步骤。RNOH(React Native for OpenHarmony)开发环境的完整配置见官方开发者指南:
https://atomgit.com/CPF-RN/docs/blob/main/开发者指南/02-搭建准备/环境初始化.md
一、版本配套:四件套必须对齐
RNOH 项目有个硬约束:RN 版本、RNOH 的 npm 包、RNOH 的 ohpm 包、DevEco SDK 四者必须对齐,错一个就是编译报错或者白屏。而且版本矩阵只是通用参考,具体库验证过的组合才算数。
我这次锁定的组合:
| 项 | 版本 |
|---|---|
expo-keep-awake | 57.0.2(与 npm 上游 latest 一致) |
| React Native | 0.84.1 |
| React | 19.2.3 |
@react-native-oh/react-native-harmony(npm) | 0.84.3 |
@rnoh/react-native-openharmony(ohpm) | 0.84.3 |
| Compile SDK | 26.0.0 |
| DevEco Studio | 26.0.0 Release |
| 实现方式 | TurboModule + CAPI 架构 |
官方 skill 的版本矩阵里 0.84 系列记的是 RNOH
0.84.2,我这版用的是0.84.3——以实际验证通过的为准,别照着矩阵硬套。
二、适配步骤
第一步:上游同步到 AtomGit
expo-keep-awake 不是独立仓库,它是 expo/expo monorepo 里的一个包:packages/expo-keep-awake。
我的做法是在 oh-react-native 组织下建一个独立仓库,把上游这个包的源码同步过来,并锁死基线 commit:
upstreamCommit: 9e5319c0f821a27b7924841903abae50e2b41790
锁 commit 这一步不能省。上游是 monorepo,包目录会跟着主仓一起动;不锁基线的话,以后想复现"这版适配对应上游哪份代码"就说不清了。这条信息我写进了仓库的 spec.json。
第二步:本地克隆
git clone https://atomgit.com/oh-react-native/expo-keep-awake.git
cd expo-keep-awake
第三步:确定交付分支与版本号
适配包和普通库不一样,它是要被别的主程按版本引用的,所以版本号必须能一眼看出"上游版本 + 鸿蒙实现版本"。
我用 main 作开发分支,完成后打 TAG 交付:
git tag 57.0.2-ohos-1.0.0
命名规则是 <上游版本>-ohos-<适配版本>。调用方按 TAG 引用,就不会被后续改动影响到:
"expo-keep-awake": "git+https://atomgit.com/oh-react-native/expo-keep-awake.git#57.0.2-ohos-1.0.0"
第四步:适配实现——新增了什么、为什么
这是核心。上游给的是 iOS/Android 实现,鸿蒙侧要从零写。
新增的第一块是 HAR 工程 harmony/keep_awake/:
harmony/keep_awake/
├── Index.ets # 导出 ExpoKeepAwakePackage
├── oh-package.json5 # 声明包名 @react-native-ohos/expo-keep-awake
├── build-profile.json5
└── src/main/
├── module.json5
├── cpp/ # CAPI 架构下的 C++ 侧
│ ├── CMakeLists.txt
│ ├── ExpoKeepAwakePackage.h
│ └── ExpoKeepAwakePackage.cpp
└── ets/
├── ExpoKeepAwakePackage.ets # 把 TurboModule 交给 RNOH
└── ExpoKeepAwakeTurboModule.ts # ★ 真正的实现
第二块是 TurboModule 的实现。上游在 JS 侧声明了三个方法,我逐个落到鸿蒙:
| JS 侧方法 | 鸿蒙实现 |
|---|---|
isAvailableAsync() | 探测当前窗口可不可用 |
activate(tag) | 把 tag 加入持有集合,设置窗口常亮 |
deactivate(tag) | 从集合移除 tag,空了就恢复原标志 |
核心就一句窗口调用:
await target.setWindowKeepScreenOn(next.size > 0 || original);
target 是当前应用窗口。这里我特意没有去改系统休眠超时,也没有创建后台运行锁——只动自己应用的窗口标志,作用域最小,不需要额外权限,也不会影响全局功耗。上游 Android 实现也是类似的选择。
original 是"接管之前这个窗口的常亮状态"。写成 next.size > 0 || original 而不是直接写 next.size > 0,是为了不擅自关掉宿主本来就设好的常亮。这个细节在第四节展开。
第三块是 package.json 里的 autolinking 声明:
"harmony": {
"alias": "expo-keep-awake",
"autolinking": {
"ohPackageName": "@react-native-ohos/expo-keep-awake",
"etsPackageClassName": "ExpoKeepAwakePackage",
"cppPackageClassName": "ExpoKeepAwakePackage",
"cmakeLibraryTargetName": "rnoh_keep_awake"
}
}
这四个名字是 RNOH 找到这个包的凭据。少一个或者拼错,表现都是"编译过了但模块没注册",运行时才发现,很难查。
第五步:补全适配仓库所需的额外文件
库的 README 和 CHANGELOG 我没动上游原文,适配相关的东西单独成文件:
| 文件 | 作用 |
|---|---|
README.OpenHarmony.md / README.OpenHarmony_CN.md | 适配说明:能力对照、版本配套、接入方式、已知限制 |
spec.json | 机器可读的适配规格:包名、模块名、方法清单、版本配套、基线 commit、验证结论 |
RN_expo-keep-awake+代码检查报告.md | 代码检查结论、真机状态与截图索引 |
harmony/keep_awake.har | 预编译产物,随包分发,装依赖即可拿到 |
spec.json 里我记了一份验证数据,方便后来人核对:
"validation": {
"status": "pass",
"date": "2026-09-13",
"systemVersion": "OpenHarmony-7.0.0.105",
"contractTests": 6,
"deviceScenarios": 6,
"screenshots": 6,
"hapSha256": "043153d1915b1761f228289bb9af851cf82cfdc71daf66baf364f031b1b8f4c9",
"releaseTag": "57.0.2-ohos-1.0.0"
}
hapSha256 是当时产物的哈希。以后有人怀疑"你验的那版和现在这版是不是同一份",对一下哈希就知道。
第六步:代码推送
git push origin main
git push origin 57.0.2-ohos-1.0.0
三、这个适配包长什么样
克隆下来第一眼会有点意外:它没有 example/,也没有可运行的应用。
expo-keep-awake/
├── package.json # 含 harmony.autolinking
├── spec.json # 适配规格
├── src/
│ ├── index.ts # JS 侧 API
│ └── NativeKeepAwake.ts
├── harmony/
│ ├── keep_awake.har # 预编译产物(3.2 KB)
│ └── keep_awake/ # HAR 源码
└── README.OpenHarmony*.md
两个要点:
- 它是"带原生实现的适配包"。和纯 JS 库不同,它必须编译原生代码,所以不能只
npm install就完事,还要走 ohpm 和 hvigor。 files字段里包含harmony,所以从 git 装依赖时能直接拿到 HAR。
"files": ["src", "harmony", "LICENSE", "README.OpenHarmony.md", "README.OpenHarmony_CN.md"]
四、接入宿主:只有三处改动面
库本身不能独立运行,必须有一个 RNOH 宿主 App。社区已有现成的——oh-react-native/RNOH084Demo 是 RNOH 0.84.3 的多库验证宿主,版本和我这版适配完全一致,而且自带一个很实用的机制:
// harmony/entry/src/main/ets/entryability/EntryAbility.ets
const rnAppKey = want.parameters?.['rnAppKey'] as string | undefined;
AppStorage.setOrCreate('rnAppKey', rnAppKey ?? 'RNOH084Demo');
Index.ets 里 RNApp 的 appKey 取自它,于是一个宿主可以挂很多独立测试页,用命令行参数切换:
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey KeepAwakeTestApp
而且它的 bundle 加载链已经是「Metro 优先 + 静态 bundle 兜底」,调代码不用改原生:
new AnyJSBundleProvider([
new MetroJSBundleProvider(),
new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
new ResourceJSBundleProvider(..., 'hermes_bundle.hbc'),
new ResourceJSBundleProvider(..., 'bundle.harmony.js')
])
接入要改的地方
第一处:package.json。
"expo-keep-awake": "file:../expo-keep-awake"
也可以按 README 写的方式装:
npm install git+https://atomgit.com/oh-react-native/expo-keep-awake.git#57.0.2-ohos-1.0.0,再跑./node_modules/.bin/react-native link-harmony。本地file:装的好处是不依赖网络,改完直接生效。
第二处:两级 oh-package.json5 都要写 HAR。
"@react-native-ohos/expo-keep-awake":
"file:../node_modules/expo-keep-awake/harmony/keep_awake.har",
harmony/oh-package.json5 管工程级、harmony/entry/oh-package.json5 管模块级,两处都要加。只加一处会出现"能找到包但链接不上"。
第三处:在 ETS 侧注册 Package。
// harmony/entry/src/main/ets/RNOHPackagesFactory.ets
import type { RNPackageContext, RNOHPackage } from '@rnoh/react-native-openharmony';
import ExpoKeepAwakePackage from '@react-native-ohos/expo-keep-awake';
export function createRNOHPackages(ctx: RNPackageContext): RNOHPackage[] {
return [
new ExpoKeepAwakePackage(ctx),
];
}
代码写在哪,这里说清楚:接入的全部改动面就是这三个文件。C++ 侧不用手改——CAPI 架构下 PackageProvider.cpp 会自动消费 autolinking 生成的 RNOHPackagesFactory.h。
五、实现上的三个设计点
点一:用 tag 集合管理持有者
上游的语义是"按标签持有":多个业务方各自持有一个 tag,谁都不释放就一直常亮。我用 Set<string> 记当前持有者:
private tags: Set<string> = new Set<string>();
private change(tag: string, activate: boolean): Promise<void> {
if (!activate && !this.tags.has(tag)) return; // ← 释放未知 tag 直接返回
const next = new Set<string>(this.tags);
if (activate) next.add(tag);
else next.delete(tag);
await target.setWindowKeepScreenOn(next.size > 0 || original);
this.tags = next; // ← 设置成功后才提交
}
两个细节值得说:
- 先复制再改、成功后才提交:
next是新集合,只有setWindowKeepScreenOn成功返回后才this.tags = next。原生设置失败时,持有者集合不会被改坏,调用方可以重试。 - 释放未知 tag 是 no-op:
if (!activate && !this.tags.has(tag)) return;。某个业务方重复释放、或者释放自己从没申请过的 tag,都不会误伤别人持有的常亮。这一点我专门测了。
点二:恢复"接管前的原值",而不是硬置假
await target.setWindowKeepScreenOn(next.size > 0 || original);
original 是接管之前窗口的常亮状态。只要有任意一个 tag 还持有就保持常亮;全部释放了,恢复成原来的值,而不是硬置为 false。 如果宿主本来就设了常亮,我不会擅自关掉它。
模块销毁时同样恢复:
await this.boundWindow.setWindowKeepScreenOn(this.originalKeepOn);
this.tags.clear();
窗口已经销毁时只记一条警告,不抛错:
hilog.warn(0x0000, 'ExpoKeepAwake', 'Window unavailable during wake-lock cleanup');
点三:addListener 保持"不可用"
export function addListener(...): EventSubscription {
const error = Object.assign(new Error('ExpoKeepAwake.addListenerForTag is unavailable on harmony'), {
name: 'UnavailabilityError', code: 'ERR_UNAVAILABLE',
});
throw error;
}
上游的 addListener 监听的是浏览器 wake-lock 的释放事件,原生平台本来就没有。我没有假装支持,而是和 iOS/Android 一样抛 ERR_UNAVAILABLE。
这一点很关键:调用方按平台写降级逻辑时,行为要一致。如果鸿蒙返回一个"永不回调的订阅",对方会以为监听成功了,问题要到很久以后才暴露。
六、构建与运行
# 1) 装 JS 依赖
npm install
# 2) 生成调试签名 + 装 ohpm 依赖
cd harmony
devecocli signature generate
ohpm install --all
# 3) 打包 JS bundle(输出到 harmony/entry/src/main/resources/rawfile/)
cd ..
npm run dev
# 4) 编译 HAP
cd harmony
hvigorw --mode module -p product=default -p module=entry@default assembleHap --no-daemon
# 5) 安装 + 启动测试页
hdc install -r entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey KeepAwakeTestApp
耗时要有心理准备:首次原生编译 37 分 50 秒,其中 BuildNativeWithNinja 一项就 37 分 6 秒。RNOH 的 C++ 体量大,而且我为模拟器放开了两个 ABI(arm64-v8a + x86_64)。增量构建快得多。
还有个容易误判的地方:hvigor 打完 CompileArkTS 那一行之后就不再逐行输出了,原生阶段可能几十分钟没有新日志。别以为卡死了——去看进程,clang++ 还在跑就是正常的。
七、踩坑记录
坑一:宿主的 package-lock.json 会拦住你
裁剪完宿主依赖后直接 npm install:
npm error code EMISSINGTARGET
npm error Missing target in lock file: "../../private/tmp/lib_react-native-annotated-text"
锁文件里还记着已删掉的依赖。删 package-lock.json 和 node_modules 重装即可。
坑二:metro.config.js 指向不存在的目录
Error "ENOENT" reading contents of "...\react-native-image-pixelmap", skipping.
Failed to construct transformer: ENOENT: no such file or directory, stat
'...\react-native-document-scanner-plugin'
watchFolders 只留真正存在的那个:
watchFolders: [path.resolve(__dirname, '../expo-keep-awake')],
顺带一个知识点:本地
file:依赖在 node_modules 里是 symlink,不把库的真实目录加进watchFolders,metro 解析不到它的源码。
坑三:babel.config.js 里挂着已删依赖的插件
error index.js: Cannot find module 'react-native-worklets/plugin'
宿主原来给 reanimated 系库挂了 worklets 插件,依赖裁掉了,插件也得删。
坑四:compatibleSdkVersion 太低会构建期被拦
00306004 Specification Limit Violation
Error Message: The project's compatibleSdkVersion: 12 cannot be lower than
the minimum compatible version 17 required by the dependencies:
@react-native-ohos/expo-keep-awake.
宿主原来是 5.0.0(12),而 HAR 声明的最低兼容版本是 API 17。抬到 5.1.0(18) 即可。
这个报错本身是好事:说明 HAR 的 module.json5 里声明了自己的最低兼容版本,依赖方过低会在构建期被直接拦下,而不是等到运行时才炸。做适配包时应该在 module.json5 里如实声明这个版本。
坑五:模拟器是 x64,默认只编 arm64
宿主 build-profile.json5 里没有 abiFilters,默认只出 arm64-v8a,装到 ohos-x64 模拟器上直接失败。要显式放开:
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"abiFilters": ["arm64-v8a", "x86_64"]
}
}
代价是编译量翻倍——这也是首次构建 38 分钟的原因之一。只上真机的话可以去掉 x86_64。
坑六:DEVECO_HOME 指向了错的 DevEco
这台机器上装了两个 DevEco Studio:C:\Program Files\Huawei\DevEco Studio(6.1.1.280)和 E:\dev\DevEco Studio(26.0.0.621)。环境检测脚本按"默认安装路径"探测,一开始取的是 C 盘那个,还把 SDK 连带读成 6.1.1.125 / API 24。把 DEVECO_HOME 指向 E 盘后立刻变成 26.0.0.621 + SDK 26.0.0.32 / API 26。
脚本报的版本不一定是你以为的那个安装,配完环境要回读一次确认。
八、真机验证
验证环境:Pura X View 模拟器,HarmonyOS 7.0.0(26.0.0) Beta2,API 26,ohos-x64。
我写了一个自检台测试页,覆盖五个能力:可用性探测、按 tag 激活/释放、Hook 挂载释放、addListener 边界、事件记录列表。
可用性与按 tag 操作:
[keep-awake-test] isAvailableAsync() -> true
[keep-awake-test] activateKeepAwakeAsync('reading') -> ok
[keep-awake-test] activateKeepAwakeAsync('reading') -> ok ← 重复激活,幂等
[keep-awake-test] activateKeepAwakeAsync('video') -> ok
[keep-awake-test] deactivateKeepAwake('reading') -> ok ← 此时 video 仍持有
[keep-awake-test] deactivateKeepAwake('video') -> ok


Hook 的挂载与释放:
[keep-awake-test] HookHolder mounted -> useKeepAwake('hook-tag')
[keep-awake-test] HookHolder unmounted -> release('hook-tag')

addListener 边界:
[keep-awake-test] addListener() -> UnavailabilityError / ERR_UNAVAILABLE(符合预期:鸿蒙不支持 Web wake-lock 事件)

原生侧确认 TurboModule 真的注册了:
RNInstance::TurboModuleProvider TM created: ExpoKeepAwake
TurboModuleFactory.cpp:54> Creating Turbo Module: ExpoKeepAwake
RNOH084Demo --> onCreate rnAppKey=KeepAwakeTestApp
能力对照
| 能力 | 结果 |
|---|---|
isAvailableAsync() | ✅ 返回 true |
activateKeepAwakeAsync(tag) | ✅ 按 tag 持有;相同 tag 重复激活幂等 |
deactivateKeepAwake(tag) | ✅ 释放对应 tag;未知 tag 为 no-op |
useKeepAwake(tag) | ✅ 挂载激活、卸载释放 |
addListener(...) | ✅ 抛 UnavailabilityError / ERR_UNAVAILABLE |
九、已知限制
一、常亮只作用于当前窗口。 应用退到后台、窗口销毁、或者系统电源策略介入时,仍由系统说了算。这个库解决的是"前台不被息屏",不是"设备不睡"。
二、不修改系统休眠超时,也不创建后台运行锁。 这是刻意的选择——改系统设置需要更高权限,创建后台锁影响全局功耗。只用应用自己的窗口标志,作用域最小、不需要额外权限。
三、窗口常亮标志本身没有系统侧读数。 验证做到了三条证据:① JS 侧每个 API 的返回值;② 原生 hilog 里的 TM created: ExpoKeepAwake(证明走的是真实实现,不是空壳);③ 源码里确实调用 setWindowKeepScreenOn。但想读窗口的 keepScreenOn 位时被挡住了:
hdc shell hidumper -s WindowManagerService -a '-a' → 输出 0 字节
hdc shell 的身份是 uid=2000(shell),对这个系统服务没有 dump 权限。所以我把这一条也留在 spec.json 的 limits 里,不当成已验证。
四、物理息屏时序未测。 有全局屏幕超时覆盖生效时,没法可靠地验证"该睡的时候会不会睡"。这条同样是 spec.json 里如实记录的限制。
五、其他 ROM / 设备未验证。 适配方记录的是 OpenHarmony-7.0.0.105;本次在 HarmonyOS 7.0.0(26.0.0) Beta2 模拟器上通过。不同厂商 ROM 的窗口策略可能不同。
六、多个库同时改同一窗口标志时需要业务协调。 我会恢复"接管前"的原值,但如果另一个库也在改同一个标志,最终状态取决于调用顺序。
十、常见问题
Q:为什么不能直接 npm install expo-keep-awake?
A:npm 上那个包只有 iOS/Android 实现,没有鸿蒙原生代码。本仓库是独立的鸿蒙实现,要按 git+...#57.0.2-ohos-1.0.0 或者本地 file: 的方式装。README 里也写明了这一点。
Q:装了之后要不要额外依赖 expo-modules-core?
A:不需要。这版是按 RNOH 的 TurboModule + autolinking 规范实现的,package.json 里的 harmony 字段就是它接入 RNOH 的全部凭据,不依赖 Expo 的模块框架。
Q:activateKeepAwake 和 activateKeepAwakeAsync 用哪个?
A:用异步版。同步版是上游的弃用接口,调用时会打 console.warn,内部还是转发到异步实现。保留它只是为了兼容老代码。
Q:重复激活同一个 tag 会不会报错?
A:不会,是幂等的。Set 语义天然去重,验证时连续调用两次 activateKeepAwakeAsync('reading') 都返回 ok。
Q:释放一个我从没申请过的 tag 会怎样?
A:什么都不做。实现里有 if (!activate && !this.tags.has(tag)) return;,避免误伤其他业务方持有的常亮。这和其他平台的语义一致,也专门验证过。
Q:在鸿蒙上 addListener 为什么直接抛异常?
A:因为它监听的是浏览器 wake-lock 释放事件,原生平台没有这个概念。我的选择是和 iOS/Android 保持一致地抛 ERR_UNAVAILABLE,而不是静默返回一个永不回调的订阅——后者会让调用方以为监听成功了。代码里用到它的话要按平台降级。
Q:为什么我在模拟器上编译要 38 分钟?
A:RNOH 的 C++ 原生库体量大,而且为了跑 ohos-x64 模拟器放开了两个 ABI,编译量翻倍。只上真机的话去掉 x86_64 会明显缩短;同工程二次构建是增量的,也快得多。
Q:怎么确认库真的生效了,而不是只是没报错?
A:三条证据一起看:① JS 侧每个 API 的返回值;② 原生 hilog 里的 TM created: ExpoKeepAwake(证明 TurboModule 注册成功,不是走了空实现);③ 读源码确认调用了 setWindowKeepScreenOn。想看第四层证据(窗口标志位)得在真机上观察息屏行为——这条我还没做到,见"已知限制"。
Q:宿主里为什么会有 rnAppKey 这种东西?
A:那是 RNOH084Demo 宿主自带的机制——一个宿主挂多个库的独立测试页,用命令行参数切换,互不干扰。--ps rnAppKey KeepAwakeTestApp 就是启动本库的测试页。做多库验证时非常省事。
小结
这个库本身很小——核心实现不到 60 行,API 只有五个。但适配过程把 RNOH 接入的完整链路过了一遍:
- autolinking 的四个身份名(ohpm 包名、ETS 包类、C++ 包类、CMake 目标),少一个都是"编译过了但模块没注册";
- HAR 的工程级与模块级双重声明,缺一处就链接不上;
- 版本四件套必须对齐,且以实测组合为准;
- HAR 里的
compatibleSdkVersion有约束力,依赖方版本过低会在构建期被拦下。
几个我认为最值得记的设计选择:
next.size > 0 || original是这版实现的核心一行——恢复"接管前的状态"而不是硬置假,宿主本来就常亮时不会被擅自关掉;addListener选择抛异常而不是静默——宁可让调用方明确知道"这个平台不支持",也不给一个假的订阅;- 只在窗口层面做常亮,不碰系统休眠超时、不建后台锁,把作用域压到最小。
适配本身之外,这次也更清楚地看到:RN 库的"能跑起来"和"能装进宿主"是两件事。库自己只有 src/ + harmony/,没有 example/;真正跑起来靠的是宿主。而社区那个 RNOH084Demo 宿主——自带 rnAppKey 多测试页切换——把这一步的成本压得很低。
本篇用到的库
| 项 | 内容 |
|---|---|
| 三方库 | expo-keep-awake(上游 57.0.2 的鸿蒙适配版) |
| 适配仓库 | https://atomgit.com/oh-react-native/expo-keep-awake |
| 适配 TAG | 57.0.2-ohos-1.0.0 |
| ohpm 包名 | @react-native-ohos/expo-keep-awake |
| HAR | harmony/keep_awake.har |
| 基线 commit | 9e5319c0f821a27b7924841903abae50e2b41790 |
| 宿主工程 | RNOH084Demo(测试页 rnAppKey = KeepAwakeTestApp) |
"expo-keep-awake": "git+https://atomgit.com/oh-react-native/expo-keep-awake.git#57.0.2-ohos-1.0.0"
// harmony/oh-package.json5 与 harmony/entry/oh-package.json5 都要加
"@react-native-ohos/expo-keep-awake":
"file:../node_modules/expo-keep-awake/harmony/keep_awake.har",
验证环境
| 项 | 版本 |
|---|---|
| React Native | 0.84.1 |
| React | 19.2.3 |
| RNOH(npm / ohpm) | @react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3 |
| Node.js | v24.14.0 |
| DevEco Studio | 26.0.0.621 |
| HarmonyOS SDK | API 26(26.0.0.32) |
| 设备 | HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64) |
| 宿主 HAP 产物 | entry-default-signed.hap(75.4 MB) |
欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN
React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native
RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview
更多推荐



所有评论(0)