Day1:React Native for OpenHarmony(RNOH)新手:环境就绪 + 真机运行验证(含 React 学习结构)

作为刚开始接触 OpenHarmony、DevEco Studio 和 React 的初学者,Day1 给自己的目标是:按“Windows 11 + DevEco Studio + OpenHarmony SDK + React Native for OpenHarmony(RNOH)”这条常见流程,把链路完整跑通一次:创建工程 → 集成 RN → 真机运行 → 用最小 React 示例验证交互

本篇你能收获什么(React 学习结构)

  • 工程层面:把 RN 页面跑到 OpenHarmony 真机上
  • React / RN 侧(通用能力)
    • 组件渲染:函数组件 + JSX
    • 状态更新:useState
    • 副作用:useEffect
    • 事件交互:onPress
  • OpenHarmony / ArkTS 侧(平台能力)
    • UIAbility / Entry / 页面入口(EntryAbility.etsIndex.ets
    • RN 容器:RNAppappKeyjsBundleProvider
    • 调试与排错:白屏、bundle、同步工程

一. 为什么选择从 React Native for OpenHarmony 开始

一开始的困惑其实很简单:OpenHarmony 生态不熟,DevEco Studio 也不熟。如果一上来就写大量 ArkTS/原生代码,学习曲线会非常陡。

所以我选择先从 React Native for OpenHarmony(RNOH) 入门,用自己更熟悉的 React 思维先把 UI 跑起来,再逐步理解鸿蒙侧的结构与原理。


二. 关键环境变量配置

2.1 配置 hdc 环境变量(Path)

  • 右键“开始” → “系统” → “高级系统设置” → “环境变量”
  • 在“系统变量”中找到 Path → 编辑 → 添加 hdc 路径
  • 重要:必须指向 toolchains 目录,不是父目录

C:\Users\用户名\AppData\Local\Huawei\Sdk\default\openharmony\toolchains(默认安装在C盘)

2.2 配置 HDC_SERVER_PORT

变量名: HDC_SERVER_PORT
变量值: 7035

2.3 配置 CAPI 架构

变量名: RNOH_C_API_ARCH
变量值: 1

2.4 清理 npm 缓存(可选)

npm cache clean --force


三. 鸿蒙依赖安装与配置

3.1 添加 harmony 脚本到 package.json

{
  "scripts": {
    "harmony": "react-native bundle-harmony --dev"
  }
}

3.2 安装鸿蒙化依赖包(注意版本匹配)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

npm i @react-native-oh/react-native-harmony@0.72.90

四. 鸿蒙侧集成 RNOH

4.1 创建目录结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.2 CMakeLists.txt(关键片段)

project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
add_compile_definitions(WITH_HITRACE_SYSTRACE)
set(WITH_HITRACE_SYSTRACE 1)

add_subdirectory("${RNOH_CPP_DIR}" ./rn)

add_library(rnoh_app SHARED
  "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
  "./PackageProvider.cpp"
)

target_link_libraries(rnoh_app PUBLIC rnoh)

4.3 PackageProvider.cpp(关键片段)

#include "RNOH/PackageProvider.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {};
}

4.4 修改 build-profile.json5(确保包含 x86_64 供模拟器用)

{
  apiType: "stageMode",
  buildOption: {
    externalNativeOptions: {
      path: "./src/main/cpp/CMakeLists.txt",
      arguments: "",
      cppFlags: "",
      abiFilters: ["arm64-v8a", "x86_64"],
    },
  },
}

4.5 修改 EntryAbility.ets

import { RNAbility } from '@rnoh/react-native-openharmony';

export default class EntryAbility extends RNAbility {
  protected getPagePath(): string {
    return "pages/Index"
  }

  override onCreate(want: Want): void {
    super.onCreate(want);
    // 原有初始化代码...
  }
}

4.6 创建 RNPackagesFactory.ets

import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [];
}

4.7 Index.ets(关键配置)

import {
  AnyJSBundleProvider,
  ComponentBuilderContext,
  FileJSBundleProvider,
  MetroJSBundleProvider,
  ResourceJSBundleProvider,
  RNApp,
  RNOHErrorDialog,
  RNOHLogger,
  TraceJSBundleProviderDecorator,
  RNOHCoreContext
} from '@rnoh/react-native-openharmony';
import { createRNPackages } from '../RNPackagesFactory';

@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}

const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)

@Entry
@Component
struct Index {
  @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
  @State shouldShow: boolean = false
  private logger!: RNOHLogger

  aboutToAppear() {
    this.logger = this.rnohCoreContext!.logger.clone("Index")
    const stopTracing = this.logger.clone("aboutToAppear").startTracing();

    this.shouldShow = true
    stopTracing();
  }

  onBackPress(): boolean | undefined {
    // Ark 侧默认 back 会终止/后台,交给 RN 处理
    this.rnohCoreContext!.dispatchBackPress()
    return true
  }

  build() {
    Column() {
      if (this.rnohCoreContext && this.shouldShow) {
        if (this.rnohCoreContext?.isDebugModeEnabled) {
          RNOHErrorDialog({ ctx: this.rnohCoreContext })
        }
        RNApp({
          rnInstanceConfig: {
            createRNPackages,
            enableNDKTextMeasuring: true,
            enableBackgroundExecutor: false,
            enableCAPIArchitecture: true,
            arkTsComponentNames: []
          },
          initialProps: { "foo": "bar" } as Record<string, string>,
          appKey: "Test0121",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
          },
          jsBundleProvider: new TraceJSBundleProviderDecorator(
            new AnyJSBundleProvider([
              new MetroJSBundleProvider(),
              new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
              new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
              new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
            ]),
            this.rnohCoreContext.logger),
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}
  1. appKey 必须与 React Native 工程中 AppRegistry.registerComponent 注册的名称完全一致,否则会导致白屏。

  2. enableNDKTextMeasuringenableCAPIArchitecture 必须设置为 true,否则应用无法正常启动。

  3. 每次修改 CPP 侧代码后,必须点击 DevEco Studio 右上角的 Sync Now 同步工程。


五. 运行结果截图

已经在鸿蒙设备上看到 React Native 页面成功启动。

后续发布到 CSDN 时,会在这里补充:设备型号 / OpenHarmony 版本 / DevEco 版本 / RNOH 版本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


六. 常见问题与排查

  • 现象:白屏
    • 可能原因:appKey 不一致
    • 如何验证:对照 AppRegistry.registerComponent('xxx') 的名字
    • 解决:保持两边完全一致
  • 现象:修改 C++ 后无变化
    • 可能原因:未同步工程
    • 解决:点击 Sync Now 再构建
  • 现象:找不到 bundle / Metro 不生效
    • 可能原因:jsBundleProvider 选择了 File/Resource,但文件不存在
    • 解决:先用 MetroJSBundleProvider() 跑通,再逐步切到 file/resource

七. 环境清单

  • Windows:Windows 11
  • DevEco Studio:
  • OpenHarmony SDK:
  • React Native:
  • RNOH:@react-native-oh/react-native-harmony@0.72.90

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

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

更多推荐