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

本文记录把 react-native-paper(Material Design 组件库)适配到 HarmonyOS 的完整过程。

它做的事:一整套 Material Design 3 组件 ------ Button / Card / Chip / FAB / TextInput / Dialog / Appbar / DataTable / Snackbar / Drawer ...,

外加主题系统(Provider + useTheme + MD3Colors)。

结论:可用 ------ 而且这是这几轮里"组件渲染证据最实在"的一次。

主入口共 57 个导出 、20 个关键导出全部存在,useTheme() 返回了真实的 MD3 主题

(colors 33 个键、primary = rgba(103, 80, 164, 1)),

并且 Button / Card 的文本在布局里拿到了真实坐标 (x=504 y=1293、x=108 y=1903 等)。

本文还记下 4 个技术发现 :两个纯 JS 桩的写法、00308018 的真正修法、设备锁屏导致的假失败,以及一个我自己踩的接线脚本 bug。

★★★★★ 一、预检:大库但很干净,只缺两个"带资源"的依赖

预检项 结果
老写法九项 (createClass / React.PropTypes / ViewPropTypes / Text.propTypes / 字符串 ref / this.refs / mixins / componentWillReceiveProps / componentWillMount / getDefaultProps) ✅✅ 全部为空
ListView / isRequired ✅ 空
measure() 3 处,只在 Tooltip 里
Platform.OS 171 处 / useNativeDriver 165 处 大库必然的分支
NativeModules 6 处 ✅ 全在 Switch.tsx ,写法是 NativeModules.PlatformConstants ? ...reactNativeVersion : undefined ⇒ 有三元保护,不崩
dependencies 3 个 ⚠️ @callstack/react-theme-provider / color / use-latest-callback ⇒ 必须显式装 (file: 接入不会自动装)
peerDependencies ⚠️ react-native-safe-area-context(src 里 27 处)
图标 ⚠️ @expo/vector-icons 的 MaterialCommunityIcons(27 处)
规模 1206 文件 、src/ 174 个 、lib/commonjs + lib/module + lib/typescript + react-navigation/

⇒ 两个"带原生资源"的依赖(safe-area-context 要接窗口 inset、vector-icons 要打字体)不装,改用纯 JS 桩隔离 ------

这样才能判断"paper 本身在鸿蒙上是否可用"。

★★★★★ 二、两个纯 JS 桩:怎么让 paper 在"缺依赖"的情况下跑起来

桩 1:react-native-safe-area-context

paper 的 src 里用到四个符号:SafeAreaProvider / SafeAreaView / useSafeAreaInsets / SafeAreaInsetsContext,

其中 useSafeAreaInsets() 必须返回一个含 top/right/bottom/left 的对象(调用方会解构)。

js 复制代码
const INSETS = {top: 39, right: 0, bottom: 0, left: 0};   // 本机实测状态栏 117px = 39vp
const SafeAreaInsetsContext = React.createContext(INSETS);

const useSafeAreaInsets = () => React.useContext(SafeAreaInsetsContext) || INSETS;

const SafeAreaProvider = ({children}) =>
  React.createElement(SafeAreaInsetsContext.Provider, {value: INSETS}, children);

const SafeAreaView = React.forwardRef(({edges, mode, style, ...rest}, ref) =>
  React.createElement(View, {ref, style, ...rest}));

⇒ 把 top 填 39(真机实测值)而不是 0 ⇒ 让"避让安全区"的行为尽量接近真实。

桩 2:@expo/vector-icons

只需要"默认导出 MaterialCommunityIcons,且能当组件渲染、接受 name/size/color":

js 复制代码
const FakeIcon = ({name, size = 24, color = '#000'}) => {
  const label = String(name).slice(0, 1).toUpperCase();
  // 一个 size×size 的带边框小方块 + 首字母
  return <View style={{width: size, height: size, borderWidth: 1, borderColor: color, ...}}>
    <Text style={{color, fontSize: size * 0.6}}>{label}</Text>
  </View>;
};
MaterialCommunityIcons.glyphMap = new Proxy({}, {get: (_t, p) => String(p)});   // ★ 需要 glyphMap
MaterialCommunityIcons.getImageSource = () => Promise.resolve(null);
MaterialCommunityIcons.loadFont = () => Promise.resolve();

⇒ 关键是要提供 glyphMap (paper 会用它把图标名映射成字形)------ 用一个 Proxy 兜住任意名字即可。

⇒ 用"小方块 + 首字母"而不是返回 null,这样图标的位置和尺寸也能在布局 dump 里看见 ✓

两个桩都通过 metro.config.js 的 extraNodeModules 顶掉:

js 复制代码
'react-native-safe-area-context': path.resolve(__dirname, 'stubs/react-native-safe-area-context.js'),
'@expo/vector-icons': path.resolve(__dirname, 'stubs/expo-vector-icons.js'),
'react-native-vector-icons': path.resolve(__dirname, 'stubs/expo-vector-icons.js'),

⇒ paper 本体一行没改,成功 bundle + 构建 + 运行 ✓

★★★★★ 三、实证:57 个导出、真实主题、真实组件坐标

导出契约(一次全过)

复制代码
NOTE | 导出总数(Object.keys 计数) = 57
PASS | ★★ 导出总数 > 20(大库)
NOTE | 导出的前 40 个键 = ActivityIndicator, AnimatedFAB, Appbar, Avatar, Badge, Banner,
       BottomNavigation, Button, Caption, Card, Checkbox, Chip, DataTable, DefaultTheme, Dialog,
       Divider, Drawer, FAB, Headline, HelperText, Icon, IconButton, List, MD2Colors, MD3Colors,
       Menu, Modal, PaperProvider, Paragraph, Portal, ProgressBar, Provider, RadioButton,
       Searchbar, SegmentedButtons, Snackbar, Subheading, Surface, Switch, Text ...
NOTE | 缺失的关键导出 = (无)
PASS | ★★★ 20 个关键导出全部存在        ← 期望=0 | 实际=0

这次我特意"只断言存在、不猜 typeof"(因为此前连续在这上面出错),形态只记在 NOTE 里:

复制代码
NOTE | Provider  = function
NOTE | Button    = object     ← forwardRef
NOTE | Card      = object     ← forwardRef
NOTE | Chip      = function
NOTE | FAB       = object     ← forwardRef
NOTE | TextInput = object     ← forwardRef
NOTE | Dialog    = function

⇒ ⇒ 印证了一件事:paper 的组件大多是 forwardRef ⇒ typeof 是 object 而不是 function。

⇒ 如果我这次写了"Button 是 function"的断言,就会白白多一条 FAIL。 这一步的克制是对的 ✓

主题系统真的在工作

复制代码
NOTE | useTheme() 返回的键 = dark, roundness, version, isV3, colors, fonts, animation
NOTE | useTheme().dark = false
NOTE | useTheme().colors 的键数 = 33
NOTE | useTheme().colors.primary = rgba(103, 80, 164, 1)
PASS | ★★ DefaultTheme 存在且有 colors

⇒ rgba(103, 80, 164, 1) 正是 Material Design 3 的默认主色(紫)✓✓

⇒ colors 有 33 个键 ------ 这是一整套完整的 MD3 调色板,说明主题系统整体可用 ✓

组件文本拿到了真实坐标

用布局 dump 里的 Text 节点坐标来定位"组件真的渲染出来了":

复制代码
✓ 「PAPER 描边按钮」    w=312  h=60  x=504  y=1293     ← Button mode="outlined"
✓ 「PAPER 文本按钮」    w=312  h=60  x=504  y=1431     ← Button mode="text"
✓ 「副标题」           w=1152 h=60  x=108  y=1810     ← Card.Title 的 subtitle
✓ 「这是 Card 的内容区」 w=1104 h=42  x=108  y=1903     ← Card.Content 里的 Text

⇒ ⇒ Button 与 Card 的文本位置、尺寸都对得上,说明这两个组件在鸿蒙上渲染正常 ✓✓

⇒ y=1293 / 1431 / 1810 / 1903 依次递增,与我页面里的书写顺序完全一致 ✓

★★★★★ 四、技术发现:00308018 的真正修法

这一轮的构建第一次是失败的:

复制代码
> hvigor ERROR: Failed :entry:default@BuildNativeWithNinja...
> hvigor ERROR: Error Code: 00308018 Unknown Error
  FAILED: [code=1] .../obj/arm64-v8a/libjsi.so
  ninja: build stopped: subcommand failed

而 bundle exit=0 (JS 打包是好的)⇒ 失败在原生侧 (libjsi.so)。

当时还有一条容易被忽略的线索:

复制代码
[metro] [Fail]TCP Port listen failed at 8081

修法 :清掉 .hvigor 与 entry/.cxx 两个缓存目录,然后全量重编

powershell 复制代码
cd E:\rnoh-work\RNOH084Demo\harmony
Remove-Item '.hvigor' -Recurse -Force
Remove-Item 'entry\.cxx' -Recurse -Force
hvigorw --mode module -p product=default -p module=entry@default assembleHap --no-daemon

结果:

复制代码
> hvigor BUILD SUCCESSFUL in 16 min 51 s 952 ms
hap 时间戳 = 10/17/2026 16:58:46

⇒ ⇒ 成功,但耗时 16 分 51 秒 (因为 .cxx 清掉后是全量重编 C++,而平时增量只要 3~4 分钟)✓

这条经验值得记下来:

00308018 + libjsi.so FAILED + ninja: build stopped ⇒

这不是 JS/依赖问题(bundle exit=0 已经排除),而是 CMake/Ninja 缓存损坏 ⇒

清 .hvigor 与 entry/.cxx 全量重编 即可恢复(代价是 17 分钟)。

★★★★ 五、一个假失败:设备锁屏

第一次安装后的启动结果是:

复制代码
error: failed to start ability.
Error Code:10106102  Error Message: The device screen is locked during the application launch,
                     unlock screen failed.
Error cause: The current mode is developer mode, and the screen cannot be unlocked automatically

⇒ App 根本没启动 ⇒ 判据 0 行、所有文本"未找到"、四张截图都是锁屏画面

⇒ 如果这时候我就下结论,会得出"paper 在鸿蒙上跑不起来"的错误判断 ✗

修法:

powershell 复制代码
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500    # 上滑解锁
hdc shell uinput -T -m 660 1900 660 500    # 再滑一次更稳

⇒ 之后再启动 ⇒ start ability successfully ✓

教训:10106102 是"设备锁屏"而不是"App 崩溃"。

遇到"启动失败 + 判据全无输出 + 截图不像我的页面"时,先看一眼启动命令的返回值 ,

不要急着怀疑库。

★★★ 六、一个我自己的接线 bug(值得记)

我给宿主工程加依赖时写了一段 PowerShell:

powershell 复制代码
foreach ($pair in @(@('react-native-paper', 'file:../react-native-paper'))) {
  $deps | Add-Member -NotePropertyName $pair[0] -NotePropertyValue $pair[1]   # ✗
}

问题 :@(@('a','b')) 在 PowerShell 里会被展平 成一个字符串数组 @('a','b'),

所以 $pair 是 字符串 、$pair[0] 取到的是第一个字符 'r'、$pair[1] 是......于是 package.json 里被写进了:

json 复制代码
"r": "f"

随后 npm install 报:

复制代码
npm error code ETARGET
npm error notarget No matching version found for f@i.

⇒ 浪费了两轮构建时间 ✗

修法 :用 -split 或直接两步赋值:

powershell 复制代码
$pkgName = 'react-native-paper'
$pkgSpec = 'file:../react-native-paper'
$deps | Add-Member -NotePropertyName $pkgName -NotePropertyValue $pkgSpec -Force

教训:PowerShell 里"嵌套数组"极易被意外展平;要配对的字面量直接写成两个变量最稳。

而且写完 package.json 要回读校验 (我这次是等到 npm install 报 notarget 才发现)。

★★ 七、本次的 1 条 FAIL(我猜错了属性名)

复制代码
NOTE | MD3Colors 的 typeof = object
NOTE | MD3Colors.primary = undefined
FAIL | ★★ MD3Colors 是 object 且有 primary | 期望=true | 实际=false

⇒ MD3Colors 里没有 primary ------ 它是一整套调色板刻度

(MD3 的命名是 primary0 / primary10 / ... / neutral0 这类),不是"语义色 + primary"那种结构。

真正带 primary 的是 DefaultTheme.colors (实测 colors 33 个键、primary = rgba(103,80,164,1))✓

⇒ ⇒ 教训:MD3Colors 与 DefaultTheme.colors 是两个不同层次的东西,我混为一谈了。

★ 八、其余预检结论

预检项 结果
外部 import @callstack/react-theme-provider / @expo/vector-icons / @react-navigation/native(可选目录)/ color / react / react-native / react-native-safe-area-context / use-latest-callback
react-navigation/ 目录 是可选集成 (adaptNavigationTheme 等),主路径不依赖
交付包形态 ✅ src/(174 个)+ lib/commonjs + lib/module + lib/typescript ⇒ 源码/产物/类型齐全
scripts.prepare ✅ 空(不需要 --ignore-scripts,但为统一仍带着)

九、接入与预检(要点)

bash 复制代码
# ① 装 paper 本体
npm install "git+https://atomgit.com/oh-react-native/react-native-paper.git#5.15.3-ohos-1.0.0" --ignore-scripts
# ② ★ 必须显式装它的 3 个运行时依赖(file: 接入不会自动装)
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4
# ③ safe-area-context 与 图标库 用纯 JS 桩隔离(见正文第二节)

十、交付包质量与基线说明

类别 结果
交付包内容 src/(174 个 ts/tsx)+ lib/commonjs + lib/module + lib/typescript + react-navigation/(可选集成) ⇒ 完整 ✓(1206 文件)
spec.json ⚠️ 缺 upstreamCommit
validation ⚠️ "build-pass-device-pending"
⚠️ 声明的基线 reactNative: "0.88.0" + rnoh: "0.84.4" ⇒ 两字段自相矛盾
备注 库代码零改动(本轮只加 polyfill/stub,未改库)

关于基线 :本次验证在 RN 0.84.1 + RNOH 0.84.3 上完成。

Platform.OS 有 171 处分支,但实测运行路径没有踩到会崩的分支 ⇒ 结论可用;换基线时建议重跑。


十一、已知限制与本次验证边界

11.1 用这个库要知道的

事项 说明
★★★★★ 有 3 个运行时依赖必须显式装 color / @callstack/react-theme-provider / use-latest-callback
★★★★★ react-native-safe-area-context 是 peerDep 27 处使用;不装需自己写桩(useSafeAreaInsets 要返回 {top,right,bottom,left})
★★★★ 图标来自 @expo/vector-icons 27 处;桩需要提供 glyphMap(可用 Proxy 兜住)
★★★★ 组件大多是 forwardRef typeof Button/Card/FAB/TextInput === 'object'(不是 function);Provider/Chip/Dialog 是 function
★★★★ useTheme() 在 Provider 内可用 返回 {dark, roundness, version, isV3, colors, fonts, animation},colors 33 键
★★★ MD3Colors ≠ DefaultTheme.colors 前者是调色板刻度(primary0/primary10...),后者才有语义色 primary
★★★ NativeModules 只用于读版本号 在 Switch.tsx,且有三元保护 ⇒ 鸿蒙上安全
★★ 主入口 57 个导出 20 个关键组件全部存在

11.2 本次验证的边界

  1. ★★★ 未验证 Chip / TextInput / FAB 各自的独立坐标(文本匹配时被我页面上的"判据要点"节点抢先命中);
  2. ★★★ 未验证 Dialog / Snackbar / Portal / Appbar / DataTable / Drawer 等其余 40+ 组件;
  3. ★★★ 未验证交互 (onPress 回调未实际点击;TextInput 未输入);
  4. ★★ 未验证 MD3 与 MD2 主题切换(只用了默认);
  5. ★★ 未验证 configureFonts 自定义字体;
  6. ★★ 未验证深色模式 (dark 实测 false,未切 true);
  7. 未验证 react-navigation/ 里的 adaptNavigationTheme;
  8. 未在 RN 0.88.0 / RNOH 0.84.4 上复验;
  9. 未测 其它屏幕宽度;未做跨平台对照。

库代码未改动 (新增的是 stubs/react-native-safe-area-context.js 与 stubs/expo-vector-icons.js)。


十二、常见问题

Q1:它在 RN 0.84 上能跑吗?

能。 57 个导出、20 个关键组件全在;useTheme() 返回真实 MD3 主题(colors.primary = rgba(103,80,164,1));

Button 与 Card 的文本拿到了真实布局坐标(x=504 y=1293 / x=108 y=1903);LogBox 无通知。

Q2:npm install 之后 Unable to resolve module color?

color / @callstack/react-theme-provider / use-latest-callback 是 paper 的 dependencies ,

而 file: 接入不会自动装它们 ⇒ 要显式装:

bash 复制代码
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4

Q3:Unable to resolve module react-native-safe-area-context / @expo/vector-icons?

两个都是"带资源"的库:前者要接窗口 inset(原生),后者要打包字体。

隔离验证时用纯 JS 桩(正文第二节有完整代码):

js 复制代码
// 前者:useSafeAreaInsets 返回 {top:39,right:0,bottom:0,left:0}
// 后者:默认导出 MaterialCommunityIcons,并提供 glyphMap(用 Proxy 兜住任意键)

Q4:构建报 00308018 + libjsi.so FAILED?

bundle 是好的、错在原生侧 ⇒ CMake/Ninja 缓存损坏。清缓存全量重编:

powershell 复制代码
cd harmony
Remove-Item '.hvigor' -Recurse -Force
Remove-Item 'entry\.cxx' -Recurse -Force
hvigorw --mode module -p product=default -p module=entry@default assembleHap --no-daemon

⚠️ 会变成全量重编 (实测 16 分 51 秒),平时增量只要 3~4 分钟。

Q5:aa start 报 Error Code:10106102 / screen is locked?

设备锁屏了,App 根本没启动(不是崩溃)。先唤醒再解锁:

powershell 复制代码
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500
hdc shell uinput -T -m 660 1900 660 500

Q6:MD3Colors.primary 是 undefined?

MD3Colors 是调色板刻度集合 (primary0 / primary10 / ... / neutral0 这类),

语义色 primary 在 DefaultTheme.colors.primary 上:

js 复制代码
import {DefaultTheme, MD3Colors} from 'react-native-paper';
DefaultTheme.colors.primary;   // 'rgba(103, 80, 164, 1)'
MD3Colors.primary10;           // 某个紫

Q7:Button 的 typeof 是 object,正常吗?

正常 ------ 它是 forwardRef 的结果。用 typeof x === 'function' 判断组件会误判。

Provider / Chip / Dialog 是普通函数组件(function),Button / Card / FAB / TextInput 是 object。

Q8:需要 --ignore-scripts 吗?

paper 自己的 scripts.prepare 是空的,所以不强制;但为了与其它库统一,我仍然带着它。


小结

react-native-paper 是一整套 Material Design 3 组件库 (主入口 57 个导出),

代码很干净(老写法九项全空、ViewPropTypes/Text.propTypes 都不用),

但它依赖两个"带资源"的库 (react-native-safe-area-context 要窗口 inset、@expo/vector-icons 要字体)

------ 这两个用纯 JS 桩隔离后,paper 本体在鸿蒙上跑得通 ✓

最值得记下来的是这几条:

  1. ★★★★★ 两个桩的写法可以直接复用。

    • useSafeAreaInsets() 必须返回对象 (调用方解构),把 top 填成真机实测的 39vp 最接近真实;
    • 图标桩要提供 glyphMap (用 Proxy 兜任意键),并且渲一个可见的小方块 而不是 null ------
      这样图标的尺寸/位置也能在布局 dump 里被看到 ✓
  2. ★★★★★ 00308018 + libjsi.so FAILED 的真正修法是"清 .hvigor + entry/.cxx 全量重编"。

    判断依据:bundle exit=0(JS 没问题)+ 错在 BuildNativeWithNinja ⇒ 是 CMake/Ninja 缓存损坏。

    代价是 16 分 51 秒 (全量重编)vs 平时 3~4 分钟(增量)✓

  3. ★★★★★ 10106102 / screen is locked 是"设备锁屏",不是"App 崩了"。

    我差点因此得出"paper 跑不起来"的错误结论 ------

    "启动失败 + 判据全无输出 + 截图不像我的页面"这三件事同时出现时,先查启动命令的返回值 ✓

  4. ★★★★★ 这一轮"只断言存在、不猜 typeof"的策略是对的。

    实测 Button/Card/FAB/TextInput 都是 object(forwardRef),

    如果我按惯性写"是 function",就会凭空多出 4 条 FAIL ✓

    形态事实先 NOTE 打出来,稳定了再断言。

  5. ★★★★ 主题系统是完整可用的 :useTheme() 返回 7 个顶层键、colors 33 键、

    primary = rgba(103, 80, 164, 1)(MD3 默认紫)✓

  6. ★★★ 组件文本的真实坐标是最硬的渲染证据 :

    Button 在 x=504 y=1293、Card.Content 在 x=108 y=1903,且 y 递增顺序与书写顺序一致 ✓

  7. ★★★ 我犯的一个接线 bug 值得记:PowerShell 的嵌套数组会被展平。

    @(@('a','b')) 里的 $pair[0] 取到的是字符 'a'[0],于是 package.json 被写进了垃圾依赖 "r":"f"

    ⇒ npm install 报 notarget No matching version found for f@i。

    修法:配对的字面量用两个变量;写完 package.json 立刻回读校验。

  8. ★★ MD3Colors 与 DefaultTheme.colors 是两层东西 (前者是刻度 primary0/primary10/...,后者才有 primary)。


本篇用到的库

项 内容
三方库 react-native-paper(上游 5.15.3 的鸿蒙适配版)
适配仓库 https://atomgit.com/oh-react-native/react-native-paper
适配 TAG 5.15.3-ohos-1.0.0
需要 HAR / 权限 / ohpm 都不需要(纯 JS)
库类型 Material Design 3 组件库(57 个导出)
运行时依赖 ⚠️ 3 个必须显式装 :color / @callstack/react-theme-provider / use-latest-callback
peerDependencies ⚠️ react-native-safe-area-context(27 处使用)
图标依赖 ⚠️ @expo/vector-icons 的 MaterialCommunityIcons(27 处)
导出形态 默认无;具名 57 个;组件多为 forwardRef(typeof 为 object)
许可证 MIT
上游仓库 https://github.com/callstack/react-native-paper
宿主工程 RNOH084Demo(测试页 rnAppKey = PaperTestApp)
bash 复制代码
npm install "git+https://atomgit.com/oh-react-native/react-native-paper.git#5.15.3-ohos-1.0.0" --ignore-scripts
npm install --ignore-scripts color@^3.1.2 "@callstack/react-theme-provider@^3.0.9" use-latest-callback@^0.2.4
tsx 复制代码
import {Provider, Button, Card, Chip, FAB, TextInput, DefaultTheme, useTheme} from 'react-native-paper';

// ① 必须用 Provider 包住(否则 useTheme 拿不到主题)
<Provider>
  <Button mode="contained" icon="check" onPress={() => {}}>确定</Button>
  <Card>
    <Card.Title title="标题" subtitle="副标题" />
    <Card.Content><Text>内容</Text></Card.Content>
  </Card>
  <Chip icon="information" onPress={() => {}}>标签</Chip>
  <TextInput label="输入" mode="outlined" />
  <FAB icon="plus" label="新建" onPress={() => {}} />
</Provider>

// ② 主题(实测可用)
const theme = useTheme();       // {dark:false, roundness, version, isV3, colors(33键), fonts, animation}
theme.colors.primary;           // 'rgba(103, 80, 164, 1)'  ← MD3 默认紫
DefaultTheme.colors.primary;    // 同上

// ⚠️ 3 个运行时依赖必须显式装(file: 接入不自动装)
// ⚠️ safe-area-context 与 @expo/vector-icons 需要装或写桩(桩要给 glyphMap)
// ⚠️ 组件大多是 forwardRef ⇒ typeof 是 'object',别用 typeof === 'function' 判断
// ⚠️ MD3Colors 是刻度集合(primary0/primary10...),语义色在 DefaultTheme.colors 上
// ⚠️ 构建报 00308018 + libjsi.so ⇒ 清 .hvigor 与 entry/.cxx 全量重编(约 17 分钟)
// ⚠️ aa start 报 10106102 ⇒ 设备锁屏,先 power-shell wakeup + uinput 上滑解锁
bash 复制代码
# 换页启动测试页 ------ force-stop 不能省
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey PaperTestApp
# 若报 10106102(锁屏):
hdc shell power-shell wakeup
hdc shell uinput -T -m 660 1900 660 500

判据的复现方式

powershell 复制代码
# ① 导出契约 + 主题
hdc shell "hilog -x | grep ppr-test" | Select-String 'PASS|FAIL|SUMMARY|NOTE'
#    ⇒ 导出总数 57;20 个关键导出全在;useTheme().colors.primary = rgba(103,80,164,1)
# ② 组件真实坐标(最硬的渲染证据)
devecocli ui layout | Select-String 'PAPER 描边按钮|这是 Card 的内容区'
#    ⇒ w=312 h=60 x=504 y=1293 / w=1104 h=42 x=108 y=1903

验证环境

项 版本
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 / npm v24.14.0 / 11.9.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),1320×2232,density 3
本机状态栏高度 117px = 39vp (safe-area 桩里按这个值填 top)
宿主依赖 ⚠️ 补装 paper 的 3 个运行时依赖 + 2 个纯 JS 桩
宿主 HAP 产物 entry-default-signed.hap
本次构建 首次失败 (00308018 / libjsi.so)⇒ 清 .hvigor + entry/.cxx 全量重编 ⇒ BUILD SUCCESSFUL(16 分 51 秒)
验证规模 导出 57 项、20 个关键导出全在 ;主题实测可用 (colors 33 键、primary 为 MD3 紫);Button/Card 文本拿到真实坐标 ;1 条 FAIL(MD3Colors.primary 我猜错) ;LogBox 无通知 ;4 张截图互异

⚠️ 基线说明 :交付包 spec.json 声明 RN 0.88.0 + RNOH 0.84.4(两字段自相矛盾 ),本次验证在 RN 0.84.1 + RNOH 0.84.3 上完成。

Platform.OS 有 171 处分支,实测运行路径未踩到会崩的分支;换基线建议重跑。


相关社区与项目地址

项目 地址
React Native 鸿蒙官方社区(CPF-RN) https://atomgit.com/CPF-RN
RNOH 框架仓库 https://atomgit.com/openharmony-RN/ohos_react_native
RNOH 三方库使用文档 https://atomgit.com/OpenHarmony-RN/usage-docs
React Native for OpenHarmony 组织 https://atomgit.com/oh-react-native
RN 三方库鸿蒙适配清单 https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

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

相关推荐
Shulex1 小时前
2026 AI 客服系统选型指南:大模型RAG GEO 2.0 时代下的买方决策卡位战
人工智能·智能客服·跨境电商
XMAIPC_Robot1 小时前
ARM+FPGA+AI船舶/工业自动化控制器EMC测试等级解析(IEC60533/IEC60945)
arm开发·人工智能·fpga开发·zynq·arm+fpga·rk3588+fpga
小姚也要变强1 小时前
机器学习基本概念
人工智能·机器学习
weixin_446260851 小时前
TraceGuard:基于执行轨迹的智能体事后溯源审计框架
人工智能
天天代码码天天1 小时前
给孩子做一本写着自己名字的迷宫书!这个小工具,生成题目、答案,还能直接打印
人工智能
m0_547486661 小时前
《人工智能》(通识课) 全套PPT课件2026
人工智能
志尊宝1 小时前
AI原生前端开发(007):AI驱动的UI生成与布局设计
人工智能·ai-native
goujunwe1 小时前
保险个人实体图谱搭建实操:全网信息统一,消除 AI 交叉校验的信息冲突
大数据·人工智能
铁皮饭盒1 小时前
CPU就行, 老照片变清晰, 本地部署582mb腾讯的模型, 本地部署, 过节了给长辈们变个小魔术
前端·javascript·后端