React Native for OpenHarmony 实战:三方库 react-native-device-name 的鸿蒙化适配指南

react-native-device-name 做的事很小:读一个"用户能看到的设备型号名"。埋点上报、设备列表、客服排查、多端登录设备管理这类场景会用到它。

它的公开 API 只有一个方法,但它是必须做原生适配的那类库------因为它的 JavaScript 只是一层壳。上游的入口文件只有三行:

js 复制代码
import { NativeModules } from 'react-native';
const { DeviceName } = NativeModules;
export default DeviceName;

真正的实现在上游的 ios/DeviceName.m 和 android/src/main/java/com/reactlibrary/DeviceNameModule.java 里。没有鸿蒙实现,所以在鸿蒙上这个原生模块根本注册不出来。

本文讲清四件事:怎么快速判断一个库"必须有原生实现"、适配要补什么、一个返回"设备相关非固定值"的接口该怎么验证、以及交付包里几处可以补的文档缺口。

环境准备 :本文不重复环境搭建步骤。RNOH(React Native for OpenHarmony)开发环境的完整配置见官方开发者指南:

https://atomgit.com/CPF-RN/docs/blob/main/开发者指南/02-搭建准备/环境初始化.md


一、先说结论:这是一个「JS 只是壳」的库

项 结论
需要原生适配吗 ✅ 需要
适配要补什么 一个鸿蒙原生模块(HAR + ArkTS TurboModule)
补的体量 ArkTS 侧 8 行 ;HAR 源码工程 9 个文件、预编译产物 2.6 KB
需要权限吗 ❌ 不需要
公开 API 只有 1 个:getDeviceName(): Promise<string>

判断依据很直接:看 package.json 有没有 harmony.autolinking。

json 复制代码
"harmony": {
  "alias": "react-native-device-name",
  "autolinking": {
    "ohPackageName": "@react-native-ohos/react-native-device-name",
    "etsPackageClassName": "DeviceNamePackage",
    "cppPackageClassName": "DeviceNamePackage",
    "cmakeLibraryTargetName": "rnoh_device_name"
  }
}

二、判定过程:怎么确认必须做原生适配

选库阶段就能判断,不用先装进来。

第一步:看 package.json 有没有 harmony 字段

bash 复制代码
npm view <包名> harmony --json

有 harmony.autolinking(ohPackageName / etsPackageClassName / cppPackageClassName / cmakeLibraryTargetName 那四个名字)的,一定是带原生实现的包 ,适配时要做 link-harmony + ohpm + hvigor 三件事。

没有这个字段 的可能是纯 JS 库,也可能像本例一样------上游没做鸿蒙适配,所以字段是后加的。所以要继续看第二步。

第二步:看上游包里有哪些平台的实现

bash 复制代码
$ npm pack react-native-device-name@1.0.0
$ tar -xzf react-native-device-name-1.0.0.tgz
$ ls package
index.js  package.json  README.md
android/  ios/  react-native-device-name.podspec

android/ 和 ios/ 两个目录都在,但没有 harmony/ ------ 这就是"必须补一个鸿蒙实现"的直接证据。

第三步:读入口文件,看它到底在做什么

js 复制代码
// package/index.js ------ 上游的全部 JS
import { NativeModules } from 'react-native';
const { DeviceName } = NativeModules;
export default DeviceName;

入口里没有任何算法,只是在取一个原生模块。 这类库的"本体"是原生实现,JS 那层换个平台就得靠新的原生模块顶上去。

反过来,如果入口里是完整的业务逻辑(字符串处理、编解码、状态机),只是偶尔 Platform.OS === 'ios' 分叉一下------那通常是"纯 JS 库 + 平台差异",优先考虑在 JS 侧解决,不一定要写原生。

三、适配实现:取值链与协作方式

交付版新增的 harmony/device_name/ 结构:

复制代码
harmony/device_name/
├── Index.ets                                   # 导出 DeviceNamePackage
├── oh-package.json5                            # 声明包名 @react-native-ohos/react-native-device-name
├── build-profile.json5
└── src/main/
    ├── module.json5
    ├── cpp/                                    # CAPI 架构下的 C++ 侧(只是个注册壳)
    │   ├── CMakeLists.txt
    │   ├── DeviceNamePackage.h                 # Package + TurboModule 工厂 + methodMap
    │   └── DeviceNamePackage.cpp
    └── ets/
        ├── DeviceNamePackage.ets               # 把 TurboModule 交给 RNOH
        └── DeviceNameTurboModule.ts            # ★ 全部实现逻辑

ArkTS 侧的全部实现只有一行取值逻辑:

ts 复制代码
import {UITurboModule} from '@rnoh/react-native-openharmony/ts';
import deviceInfo from '@ohos.deviceInfo';

export class DeviceNameTurboModule extends UITurboModule {
  async getDeviceName(): Promise<string> {
    return deviceInfo.marketName || deviceInfo.productModel || 'OpenHarmony device';
  }
}

取值链 :marketName → productModel → 兜底文本 'OpenHarmony device'。

  • marketName 是面向用户的市场名(真机上通常是 "HUAWEI Mate 60" 这类),业务展示应该优先用它;
  • productModel 是产品型号,在模拟器或未配置市场名的设备上更可能有值;
  • 最后一层是兜底 ,保证接口永远返回非空字符串------因为契约是 Promise<string>、调用方通常直接展示。

@ohos.deviceInfo 读的是系统公开参数,不需要任何权限。

C++ 侧只是个注册壳,一行业务逻辑都没有:

cpp 复制代码
class DeviceName : public ArkTSTurboModule {
 public:
  DeviceName(const ArkTSTurboModule::Context ctx, const std::string& name) : ArkTSTurboModule(ctx, name) {
    methodMap_ = {
      ARK_ASYNC_METHOD_METADATA(getDeviceName, 0),
    };
  }
};

ARK_ASYNC_METHOD_METADATA(getDeviceName, 0) ------ 方法名、0 个参数、返回 Promise。方法名或参数个数写错,表现是"编译过了但调用报方法不存在"。

JS 侧的改动:把 undefined 隐患换成"早失败"

交付版的 src/index.ts 相比上游换了取模块的方式:

ts 复制代码
import {TurboModuleRegistry, type TurboModule} from 'react-native';

export interface Spec extends TurboModule {
  getDeviceName(): Promise<string>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('DeviceName');

上游是 const { DeviceName } = NativeModules------模块没注册时得到 undefined,要等到第一次调用才炸 。交付版用 TurboModuleRegistry.getEnforcing,模块缺失时在导入阶段就抛出明确错误。

这个改动很小,但对排障很有用:接入出错时你会在启动日志里立刻看到,而不是在业务跑到某个分支时才报 Cannot read property 'getDeviceName' of undefined。

四、接入宿主:三处改动面(外加一处自动生成的)

库本身不能独立运行,必须有一个 RNOH 宿主 App。这里用社区现成的 RNOH084Demo(RNOH 0.84.3 的多库验证宿主),它自带一个 rnAppKey 机制,一个宿主可以挂很多独立测试页:

ts 复制代码
// harmony/entry/src/main/ets/entryability/EntryAbility.ets
const rnAppKey = want.parameters?.['rnAppKey'] as string | undefined;
AppStorage.setOrCreate('rnAppKey', rnAppKey ?? 'RNOH084Demo');

于是可以用命令行参数切换测试页:

bash 复制代码
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey DeviceNameTestApp

接入要改的地方

第一处:package.json。

json 复制代码
"react-native-device-name": "file:../react-native-device-name"

第二处:两级 oh-package.json5 都要写 HAR。

json5 复制代码
"@react-native-ohos/react-native-device-name":
  "file:../node_modules/react-native-device-name/harmony/device_name.har",

harmony/oh-package.json5 管工程级、harmony/entry/oh-package.json5 管模块级,两处都要加。只加一处会出现"能找到包但链接不上"。

这里有个很容易漏的点 :跑 link-harmony 时,它只会自动更新工程级那一份,模块级那份要你自己加。

第三处:在 ETS 侧注册 Package。

ts 复制代码
// harmony/entry/src/main/ets/RNOHPackagesFactory.ets
import type { RNPackageContext, RNOHPackage } from '@rnoh/react-native-openharmony';
import DeviceNamePackage from '@react-native-ohos/react-native-device-name';

export function createRNOHPackages(ctx: RNPackageContext): RNOHPackage[] {
  return [
    new DeviceNamePackage(ctx),
  ];
}

代码写在哪,这里说清楚 :手工改动面就是这三个文件(外加 metro.config.js 的 watchFolders)。C++ 侧不用手改------CAPI 架构下 PackageProvider.cpp 会自动消费 autolinking 生成的 RNOHPackagesFactory.h。

那"自动生成的一处"是什么? 执行 link-harmony 时,它会一次性重写这四个文件:

复制代码
• harmony/entry/src/main/cpp/RNOHPackagesFactory.h   # C++ 侧注册
• harmony/entry/src/main/cpp/autolinking.cmake       # add_subdirectory + 链接
• harmony/entry/src/main/ets/RNOHPackagesFactory.ets # ETS 侧注册
• harmony/oh-package.json5                           # 工程级 HAR 依赖

这四个文件头部都写着 DO NOT modify it manually, your changes WILL be overwritten.------别手改。

接入成功的两个自检信号

复制代码
$ node_modules\.bin\react-native link-harmony --verbose
[link] react-native-device-name
[skip] @react-native-oh/react-native-harmony
...
info updated 4 file(s), linked 6 libraries, skipped 1 library

[link] react-native-device-name 在列表里 ,说明 autolinking 认出了它的 harmony.autolinking。打包时 Metro 也会把它列进重定向清单:

复制代码
[INFO] Redirected imports to 6 harmony-specific third-party package(s):
[INFO] • react-native-device-name → react-native-device-name
...

这两个信号对这个库是"必须出现":有原生实现的包要被解析到它的鸿蒙实现,列表里没有它就说明没接通。

(harmony/entry/src/main/module.json5 未改动 ------本库不读任何需要权限的信息,不用加 requestPermissions。)

五、构建与运行

bash 复制代码
# 1) 装 JS 依赖 + 自动链接
npm install
./node_modules/.bin/react-native link-harmony

# 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
# 换页参数只在「冷启动」时生效:先 force-stop 再起
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey DeviceNameTestApp

耗时 :在已有原生编译缓存的宿主上增量加入这个库,assembleHap 用了 6 分 35 秒 ;HAP 从 80.09 MB 涨到 80.23 MB(约 +136 KB)。

如果宿主是全新 clone (没有原生编译缓存),首次构建会到 30--40 分钟 量级;只改 JS 重新打包也要 6--7 分钟,所以别把 UI 微调留到最后做。

看日志:

bash 复制代码
hdc shell "hilog -x | grep -i 'TM created'"
hdc shell "hilog -x | grep -i 'device-name-test'"

看界面(读无障碍树,不用截图就能拿到文本):

powershell 复制代码
devecocli ui layout

按文本点击(页面高度会随结果卡片变化,别记固定坐标):

powershell 复制代码
. E:\rnoh-work\click-label.ps1
Click-Label -Pattern '读取设备名并跑全部断言'

六、验证设计:设备相关的非固定值怎么验

这个库只有一个方法 ,而且返回值不是固定值------它取决于跑在什么设备上。

这就带来一个验证陷阱 :如果只断言"返回非空字符串",那么返回 "a"、"随便什么"、"OpenHarmony device" 都会通过------等于没验证。

所以验证要回答两个不同的问题:

问题 怎么验
接口形态对不对 返回 Promise、类型是 string、非空、无空白/控制字符、长度合理、多次调用一致
返回值对不对 与设备系统参数交叉核验(期望值由外部独立读出)

期望值从哪来:用 hdc 独立读系统参数

bash 复制代码
$ hdc shell param get const.product.marketname
Get parameter "const.product.marketname" fail! errNum is:106!     ← 不存在

$ hdc shell param get const.product.model
emulator

$ hdc shell param get const.product.name
emulator

$ hdc shell param get const.product.brand
HUAWEI

$ hdc shell param get const.product.os.dist.name
HarmonyOS

$ hdc shell param get const.product.os.dist.apiname
26.0.0

$ hdc shell param get const.product.software.version.name
HarmonyOS NEXT Developer Beta1

这一步是整个验证的关键 :期望值来自系统本身(param get),不是从被测库拿的。如果库返回一个自己编的字符串,它不可能同时等于 const.product.model 和 const.product.name。

而且这次还额外覆盖到了回退分支 :本机 const.product.marketname 不存在 ,也就是 deviceInfo.marketName 为空,所以实现必然走第二条分支取 productModel → 期望返回值是 "emulator"。

⇒ 一次验证同时确认了两件事:

  1. 值是对的 (等于系统参数给出的 productModel);
  2. 回退分支真的生效了 (marketName 为空时确实回退,而不是返回空串或抛错)。

七、真机验证

验证环境:Pura X View 模拟器,HarmonyOS 7.0.0(26.0.0) Beta2,API 26,ohos-x64。

TurboModule 注册

复制代码
RNInstance::TurboModuleProvider  TM created: DeviceName

断言结果:10 / 10 全部通过

A 组:契约与形态(7 项)

断言 结果
返回 Promise(typeof .then === 'function') ✅
返回类型是 string ✅
非空字符串 ✅
无首尾空白 ✅
无控制字符(/[\u0000-\u001f\u007f]/ 不匹配) ✅
长度不超过 64 ✅
连续三次调用结果一致 ✅

B 组:值正确性(3 项)

断言 结果
等于 const.product.model(emulator) ✅
等于 const.product.name(emulator) ✅
未落到兜底文本 'OpenHarmony device' ✅

原始读数与耗时

复制代码
[device-name-test] getDeviceName() 连续三次:"emulator" / "emulator" / "emulator"
[device-name-test] 单次耗时:31 ms / 4 ms / 0 ms
[device-name-test] A + B(契约 / 形态 / 值正确性) -> 10/10 全部通过

首次调用 31 ms (含 TurboModule 创建与 ArkTS 侧首次加载 @ohos.deviceInfo),之后 4 ms / 0 ms。这是个"读一次就能缓存"的接口,业务侧没必要反复调用。

能力对照

能力 结果
getDeviceName() 返回 Promise ✅
返回非空字符串 ✅
返回值等于设备系统参数中的 productModel ✅ 独立交叉核验通过
marketName 为空时的回退分支 ✅ 本机实测走的就是这条分支
需要权限 ✅ 不需要(宿主未新增任何 requestPermissions)
TurboModule 注册 ✅ TM created: DeviceName

八、交付包可补的地方

运行时没有问题,但交付包在可追溯性上有三处缺口,如实记下来:

一、README 里的上游地址是占位符。 README.OpenHarmony_CN.md / README.OpenHarmony.md 写的都是 github_account/react-native-device-name------这不是真实上游地址,读者按 README 找不到源仓库。应该换成上游真实地址。

二、spec.json 没记录上游仓库与基线 commit。 现有一份 spec.json 只有 name / version / module / native / description / methods / rnoh / reactNative / validation,没有 upstream 字段、也没有 upstreamCommit。对交付包来说,"我验的是上游哪一版"是核心信息------缺了它就无法复现,也无法回答"上游发新版后这版适配是否还对应"。

三、契约测试没有真正测到东西。

js 复制代码
const test = require('node:test');
const assert = require('node:assert/strict');

test('public contract returns a promise of a non-empty device name', () => {
  assert.equal(typeof 'DeviceName', 'string');
  assert.equal(typeof Promise.resolve('OpenHarmony device').then, 'function');
});

这两条断言的对象是字面量 ------typeof 'DeviceName' 永远是 'string',typeof Promise.resolve(...).then 永远是 'function'。测试没有 import 本库,也没有调用任何方法,所以无论库是否可用都会通过。这不是验证,只是占位。

根因推测 :上游 npm 包本身就是没改过的 RN 库模板 ------package/package.json 里 "description": "TODO"、"author": {"name": "Your Name", "email": "yourname@email.com"}、repository.url 指向 github_account/...。交付时把上游的占位符照抄进了 README,也没另外补 spec.json 的上游字段。

顺带一个上游打包问题 :上游 tarball 92,757 字节 里塞满了构建产物------android/build/、android/.gradle/、android/.idea/(其中 gradle_models.ser 56 KB、executionHistory.bin 32 KB)。这是上游 .npmignore 配置的问题,不是交付方引入的,但会让包体积膨胀十几倍。

九、已知限制

一、只读系统公开字段,不读用户自定义名称。 实现取的是 deviceInfo.marketName / deviceInfo.productModel,不是用户在设置里改过的设备名。如果你的业务需要"用户给设备起的名字",这个库不满足------那通常要调设置类接口,而且往往需要权限。

二、不同 ROM 的字段取值可能不同。 const.product.marketname / const.product.model 是否存在、格式如何,取决于 ROM。本次只在一台模拟器上验证,实测 marketName 为空、回退到 productModel。

三、回退到兜底文本的分支未实测。 只有 marketName 与 productModel 同时为空 时才会返回 'OpenHarmony device'。模拟器上至少有一个有值,无法构造这个场景------所以"兜底文本"这条路径只有代码层面可见,没有设备侧证据。

四、真机上的返回值很可能与模拟器不同。 真机通常有市场名(如 "HUAWEI Mate 60"),届时返回的会是 marketName 而不是 productModel。业务展示应该允许名称变化,不要把它当作稳定标识符做逻辑判断。

五、返回值不是设备唯一标识。 同一个型号名会出现在成千上万台设备上。它只适合展示,不适合做设备身份------需要唯一标识时应该用别的方案。

六、未测大并发与高频调用。 接口本身没有缓存,每次调用都会走过桥。实测首次 31 ms、后续 0--4 ms;业务侧建议自己缓存结果,不要放在高频渲染路径里。

七、其他 ROM / 真机未验证。 适配方记录的是 OpenHarmony-7.0.0.105;本次在 HarmonyOS 7.0.0(26.0.0) Beta2 模拟器上通过。

十、常见问题

Q:这个库为什么必须做原生适配?

A:它的 JS 入口只有三行------export default NativeModules.DeviceName,本体是原生实现 。上游只提供了 ios/DeviceName.m 和 android/.../DeviceNameModule.java,没有鸿蒙实现。不补一个鸿蒙原生模块,NativeModules.DeviceName 就是 undefined,调用必然失败。

Q:怎么快速判断一个库要不要做原生适配?

A:三步。① npm view <包名> harmony --json 看有没有 harmony.autolinking(有 → 一定是带原生实现的适配包);② 上游包里有哪些平台的实现目录(只有 ios/ + android/ 而没有 harmony/ → 要补一个鸿蒙实现);③ 读入口文件------如果里面只有"取原生模块"而没有任何业务逻辑,那它天生依赖原生。

Q:适配一共要改多少东西?

A:ArkTS 侧的实现逻辑只有一行(deviceInfo.marketName || deviceInfo.productModel || 'OpenHarmony device'),加上 Package/CMake/Index 的接线一共 9 个文件,预编译 HAR 只有 2.6 KB。接入宿主时手工改动面是三处 :package.json 依赖、模块级 oh-package.json5 加 HAR、RNOHPackagesFactory.ets 注册 Package。

Q:为什么返回的是 "emulator" 而不是设备市场名?

A:因为实现的取值链是 marketName → productModel → 兜底文本,而这台模拟器的 marketName 为空 (hdc shell param get const.product.marketname 返回不存在),所以回退到了 productModel(emulator)。真机上通常有市场名,返回值会不同------这也是为什么验证不能只断言"非空"。

Q:怎么验证一个"返回值不固定"的接口?

A:把验证拆成两层:① 形态层 ------返回 Promise、类型、非空、无空白/控制字符、多次一致;② 值层 ------找一个外部独立来源 作为期望值。本例用的是 hdc shell param get const.product.model,从系统本身读出期望值,而不是从被测库拿。如果库返回的是自己编的字符串,它不可能同时等于两个不同的系统参数。

Q:返回的设备名能当唯一标识用吗?

A:不能。同一个型号名会出现在大量设备上。它只适合展示。需要唯一标识请用别的方案。

Q:能不能读用户自己改的设备名?

A:不能。实现只读 @ohos.deviceInfo 的系统公开字段,不读用户自定义名称,也不需要任何权限。业务如果依赖用户自定义名称,得另找接口。

Q:spec.json 里没有上游 commit,会不会有问题?

A:不影响运行,但影响可追溯性 。交付包的价值之一是能回答"我验的是上游哪一版、上游发新版后这版是否还对得上"。缺 upstream / upstreamCommit 就答不了。README 里那个 github_account/... 也是占位符,建议一并补上。

Q:为什么我在模拟器上编译要这么久?

A:宿主已有原生编译缓存时,增量加一个库约 6--7 分钟 (hvigor 会把整套流水线走一遍);全新克隆的宿主首次编译要 30--40 分钟。只改 JS 重新打包也是 6--7 分钟。

小结

这个库的适配体量是"一行取值 + 三层接线",但有两件事值得记:

第一件是判定。 一个 RN 三方库要不要做原生适配,看三点就够了:package.json 有没有 harmony.autolinking、上游包里有哪些平台的实现目录、入口文件里有没有真实业务逻辑。本例的入口只有三行、只是在取一个原生模块 ------这类库的本体在原生侧,换个平台就必须补实现。判断对了,就清楚知道工作量在哪;判断错了(比如把一个"JS 只是壳"的库当纯 JS 用),会在运行时才发现模块是 undefined。

第二件是"非固定返回值"的验证设计。 这个库只有一个方法、返回一个随设备变化的字符串。只断言"非空"等于没验证 ------任何字符串都能过。所以要把验证拆成两层:形态层查契约,值层找外部独立来源 做交叉核验。本例用的是 hdc shell param get:期望值由系统读出,不经由被测库。这样即使库返回一个自造的字符串,也无法同时等于两个不同的系统参数。

而且这次运气不错:本机 marketName 恰好为空 ,于是实测正好走过了"回退到 productModel"这条分支------一次验证同时确认了"值是对的"和"回退逻辑真的生效"。验证一个带取值链的接口时,先弄清每条分支的触发条件,再挑一个能触发非首条分支的环境,比只测 happy path 有价值得多。

最后如实记了交付包的三处文档缺口:README 里上游地址还是占位符、spec.json 缺上游 commit、契约测试断言的是字面量(没 import 库、没调用方法,怎么跑都会通过)。这三条不影响运行时 ,但影响"这个交付包能不能被信任和复现"------一个测试如果永远不会失败,它就不是测试。


本篇用到的库

项 内容
三方库 react-native-device-name(上游 1.0.0 的鸿蒙适配版)
交付仓库 https://atomgit.com/oh-react-native/react-native-device-name
适配 TAG 1.0.0-ohos-1.0.0
ohpm 包名 @react-native-ohos/react-native-device-name
HAR harmony/device_name.har(2.6 KB)
原生模块名 DeviceName
是否需要权限 不需要
宿主工程 RNOH084Demo(测试页 rnAppKey = DeviceNameTestApp)
json 复制代码
"react-native-device-name": "git+https://atomgit.com/oh-react-native/react-native-device-name.git#1.0.0-ohos-1.0.0"
json5 复制代码
// harmony/oh-package.json5 与 harmony/entry/oh-package.json5 都要加
"@react-native-ohos/react-native-device-name":
  "file:../node_modules/react-native-device-name/harmony/device_name.har",
ts 复制代码
import DeviceName from 'react-native-device-name';

const name = await DeviceName.getDeviceName();   // 例如 "emulator" / "HUAWEI Mate 60"
bash 复制代码
# 换页启动测试页(force-stop 不能省,换页参数只在冷启动生效)
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey DeviceNameTestApp

验证环境

项 版本
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)
本机 const.product.model emulator
本机 const.product.marketname 不存在(errNum 106)
宿主 HAP 产物 entry-default-signed.hap(80.23 MB)
本次增量构建 assembleHap 6 分 35 秒
验证规模 设备侧 10 项断言全通过 + 与系统参数交叉核验

欢迎加入 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

相关推荐
高洁011 小时前
AI视频生成技术:从静态图文到动态视觉的内容智能革命
python·深度学习·django·transformer·tornado
阳明山水1 小时前
CEDAR双重解耦实现决策与干预分离
人工智能·深度学习·算法·机器学习·架构
三掌柜6661 小时前
ArkWeb 手记 07|缓存和离线页怎么做
缓存·harmonyos
HwJack201 小时前
【共创稿事节】 HarmonyOS 7从 2D 到 3D:空间计算带来的到底是什么范式变革
3d·harmonyos·空间计算
倔强的石头1061 小时前
【Transformer】Tokenization详解_BPE_WordPiece_SentencePiece
android·深度学习·transformer
Zootopia6262 小时前
美国载人飞船Crew-13明晚发射!
人工智能·算法·机器学习·数学建模·无人机·创业创新·信息与通信
探客木木夕2 小时前
AI伦理体系核心价值观声明
大数据·人工智能·机器学习
明志数科2 小时前
具身智能训练数据分布设计:为什么分布比数量更关键
人工智能·深度学习·机器学习
啥都鼓捣的小yao2 小时前
自主机器人基础
人工智能·深度学习·机器人