惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
IT之家
IT之家
Google DeepMind News
Google DeepMind News
罗磊的独立博客
爱范儿
爱范儿
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
U
Unit 42
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
B
Blog
博客园 - 叶小钗
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
C
Check Point Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

博客园 - zhengyan_web

极光推送集成记录 xcode 打包 报错 main.jsbundle does not exist. react-native-background-job 加载依赖报错处理 解决gradle与gradle plugin匹配关系以及gradle下载缓慢的问题 ‌华为手机记录密码后页面显示的用户名可以通过修改设置来隐藏 极狐gitlab 搭建 rn node 版本问题 mac 电脑查看已安装的谷歌插件 xcode 15打包报错 网络代理 mac jdk切换 js编码、解码方法(escape,encodeURI,encodeURIComponent区别及用法) grep命令 苹果审核Guideline 2.3.1 - Performance XCode报错Thread 1: EXC_BAD_ACCESS (code=2, address=0x....) mac m1 运行老项目 docker 安装homebrew报错error: Not a valid ref: refs/remotes/origin/master 的解决方法 React Native 新版 pod install 依赖时报错
rn 适配 鸿蒙
zhengyan_web · 2026-04-04 · via 博客园 - zhengyan_web

参考:

1、https://gitcode.com/OpenHarmony-RN/ohos_react_native/blob/master/docs/zh-cn/%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/RN%E5%BA%94%E7%94%A8%E9%B8%BF%E8%92%99%E5%8C%96%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97.md
2、https://gitcode.com/OpenHarmony-RN/ohos_react_native/blob/master/docs/zh-cn/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md 

环境:

  node -> v18.16.0

  DevEco Studio  -> Build Version: 6.0.0.878

1、创建RNJS新项目

  1)、目前 React Native for OpenHarmony 仅支持 0.72.5 版本的 React Native:

    npx react-native@0.72.5 init GuidePro --version 0.72.5

    或者

    npx react-native@0.72.5 init GuidePro --version 0.72.5 --skip-install (推荐使用 --skip-install 跳过ios的依赖,下载较慢或者报错,ios依赖和鸿蒙项目无关)

  2)、 安装鸿蒙版本RN依赖包 

    目录下运行   npm i @react-native-oh/react-native-harmony@x.x.x

    版本说明: 根据自己安装的鸿蒙开发工具来, 当前devEco-studio 版本是 6.0.0878

            image

    我这里选的是 0.72.86 版本

  3)、打开rn项目在目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:

    "harmony": "react-native bundle-harmony --dev"

    如下图

           image

  4)、为了获取获取鸿蒙的bundleJS

    修改rn 项目下的 metro.config.js 文件 内容修改如下    

const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config'); 
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');  

/*** @type {import("metro-config").ConfigT}*/ 
const config = {
 transformer: {
   getTransformOptions: async () => ({
     transform: {
       experimentalImportSupport: false,
       inlineRequires: true,
     },
   }),
 },
};  
module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({ reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony', }), config);

  5)、运行在rn 项目下 运行  npm run harmony 

  6)、运行完上面指令后,可在rn项目的路径下:项目名称//harmony/entry/src/main/resources/rawfile 生成 bundle.harmony.js 和 assets 文件 ,保存好这俩个文件 呆会需要把他们拷贝到 鸿蒙工程项目下使用

2、创建RN鸿蒙壳工程

  1)、创建鸿蒙工

    image

  2)、在entry下新建package.json文件,里面导入react-native-oh包 如下

{
  "name": "SinochemUbmpOHApp",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "@react-native-oh/react-native-harmony":"0.72.86"
  },
  "devDependencies": {
    "react-native": "0.72.5"
  }
}

  3)、在entry下 执行 npm i  

  4)、在entry下  oh-package.json5  下的  dependencies  添加本地依赖  "@rnoh/react-native-openharmony": "file:./node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har"

  5)、在编辑器上 点击同步 

    image

  6)、补充CPP侧代码

    在 GuidePro/entry/src/main 目录下新建 cpp 文件夹

    a、在 cpp 目录下新增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) # for other CMakeLists.txt files to use

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

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

target_link_libraries(rnoh_app PUBLIC rnoh)

    b、在 cpp 目录下新增PackageProvider.cpp

#include "RNOH/PackageProvider.h"  
using namespace rnoh;  
std::vector<std::shared_ptr<Package>> 
PackageProvider::getPackages(Package::Context ctx) {
   return {};
}

    c、打开GuidePro\entry\build-profile.json5,将 cpp 中的代码添加到鸿蒙的编译构建任务中

{
  "apiType": "stageMode",
  "buildOption": {
    "externalNativeOptions": {
      "path": "./src/main/cpp/CMakeLists.txt",
      "arguments": "",
      "cppFlags": "",
      // "abiFilters": ["arm64-v8a", "x86_64"]
    },
    "resOptions": {
      "copyCodeResource": {
        "enable": false
      }
    }
  },
  "buildOptionSet": [
    {
      "name": "release",
      "arkOptions": {
        "obfuscation": {
          "ruleOptions": {
            "enable": false,
            "files": [
              "./obfuscation-rules.txt"
            ]
          }
        }
      }
    },
  ],
  "targets": [
    {
      "name": "default"
    },
    {
      "name": "ohosTest",
    }
  ]
}

  7、补充ArkTS侧的代码

    a、打开GuidePro\entry\src\main\ets\entryability\EntryAbility.ets引入并使用RNAbility

import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { RNAbility } from "@rnoh/react-native-openharmony";

const DOMAIN = 0x0000;

export default class EntryAbility extends RNAbility {

  protected getPagePath(): string {
    return 'pages/Index';
  }
  override onCreate(want: Want): void {
    super.onCreate(want);
    hilog.info(0x0000, 'testTag', '%{public}s', 'EntryAbility onCreate');
  }

  onDestroy(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created, set main page for this ability
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    });
  }

  onWindowStageDestroy(): void {
    // Main window is destroyed, release UI related resources
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

  b、在GuidePro\entry\src\main\ets\rn目录下新增RNPackagesFactory.ets

import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [];
}

  c、打开GuidePro\entry\src\main\ets\page\Index.ets 文件替换如下

import {
  AnyJSBundleProvider,
  ComponentBuilderContext,
  FileJSBundleProvider,
  MetroJSBundleProvider,
  ResourceJSBundleProvider,
  RNApp,
  RNOHErrorDialog,
  RNOHLogger,
  TraceJSBundleProviderDecorator,
  RNOHCoreContext } from '@rnoh/react-native-openharmony';
import { createRNPackages } from '../rn/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 {
    // NOTE: this is required since `Ability`'s `onBackPressed` function always
    // terminates or puts the app in the background, but we want Ark to ignore it completely
    // when handled by 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, // 该项必须为true,用于开启NDK文本测算
            enableBackgroundExecutor: false,
            enableCAPIArchitecture: true, // 该项必须为true,用于开启CAPI
            arkTsComponentNames: []
          },
          initialProps: {  } as Record<string, string>, // 传参
          appKey: "XXXX", // 注意 这个必须要用rn 项目的名称, 刚才创建rn 项目使用的命令是 npx react-native@0.72.5 init GuidePro --version 0.72.5  所以这里的 XXX 就是 GuidePro
 wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder, onSetUp: (rnInstance) => { rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP") }, jsBundleProvider: new TraceJSBundleProviderDecorator( new AnyJSBundleProvider([ new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')]), this.rnohCoreContext.logger), }) } } .height('100%') .width('100%') } }

3、整合资源

  1)、把第一步rn生成的 bundle.harmony.js 和 assets 文件 拷贝到  鸿蒙工程目录下的 项目/entry/src/main/resources/rawfile 文件夹 下面

    image

  2)、使用鸿蒙开发工具 运行项目 (如果要真机运行,必须要先签名 否则报错)

    image