本次项目创建参考了三篇大佬的文章

https://blog.csdn.net/weixin_74220422/article/details/155141118?sharetype=blog&shareId=155141118&sharerefer=APP&sharesource=weixin_74220422&sharefrom=link

https://gitcode.com/openharmony-sig/ohos_react_native/blob/master/docs/zh-cn/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md?mode=light&isLogin=1

https://blog.csdn.net/qq_74796274/article/details/155077369?spm=1001.2014.3001.5502

一、配置项目运行环境

1.1hdc环境配置

hdc 是 OpenHarmony 为开发人员提供的用于调试的命令行工具,鸿蒙 React Native 工程使用 hdc 进行真机调试。hdc 工具通过 OpenHarmony SDK 获取,存放于 SDK 的 toolchains 目录下,请将 {DevEco Studio安装路径}/sdk/{SDK版本}/openharmony/toolchains 的完整路径添加到环境变量中。

在系统变量中增加下面红色框内内容

变量名为HDC_SERVER_PORT

变量值可设置为任意未被占用的端口,如 7035

1.2配置 CAPI 版本环境变量

当前RN框架提供的 Demo 工程默认为 CAPI 版本,需要配置环境变量 RNOH_C_API_ARCH = 1

在此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,在系统变量中点击新建

添加变量名为:RNOH_C_API_ARCH

变量值为 1

1.3编辑用户级 .npmrc 配置文件

为了使用加速 npm 包的下载,可以配置镜像源;如果关闭 SSL 证书校验还可以进一步加速下载,但是这会降低安全性,需用户评估后再使用。配置文件位置在 C:\Users\用户名\.npmrc(Windows)或者 ~/.npmrc(macOS),如果没有则手动创建。供参考的 .npmrc 配置文件内容如下:

strict-ssl=false
sslVerify=false
registry=https://repo.huaweicloud.com/repository/npm/

修改 registry 后需执行 npm cache clean --force 清理缓存,以确保新的 registry 生效。

二、创建React Native工程

2.1创建AwesomeProject目录

可选择一个目录,例如 D 盘根目录,使用 React Native 内置的命令行工具来创建一个名为 “AwesomeProject” 的新项目。这个命令行工具不需要安装,可以直接用 node 自带的 npx 命令来创建,目前 React Native for OpenHarmony 仅支持 0.72.5 版本的 React Native:

此处我选择了reactproject作为项目根目录

进入该文件夹终端输入下面命令

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

执行完成之后reactproject文件夹下面就会生成AwesomeProject目录

2.2下载并安装鸿蒙化依赖

这里一定要根据自己的DevEco Studio版本安装相应的依赖

先打开DevEco Studio查看版本

我的版本是6.0.1

再点击下面的链接去查看版本对应的相关依赖

https://link.csdn.net/?from_id=155077369&target=https%3A%2F%2Fgitcode.com%2Fopenharmony-sig%2Fohos_react_native%2Fblob%2Fmaster%2Fdocs%2Fzh-cn%2F%25E7%2589%2588%25E6%259C%25AC%25E8%25AF%25B4%25E6%2598%258E.md

我这里能找到适配的依赖是0.72.90

打开 AwesomeProject 目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:

然后执行"npm i @react-native-oh/react-native-harmony@x.x.x",这里最好指定一下版本,比如刚刚我们找到我的DevEco Studio是6.0.1版本,React下载的版本最好是0.72.90。所以命令可以改为"npm i @react-native-oh/react-native-harmony@0.72.90",在刚刚生成好的AwesomeProject文件夹终端执行这个命令

命令运行完成功之后依赖就安装完成了

2.3运行指令并生成bundle

打开 AwsomeProject\metro.config.js,并添加 OpenHarmony 的适配代码。

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);

上面代码替换完后在 AwesomeProject 目录终端运行生成 bundle 文件的命令。运行成功后,AwesomeProject/harmony/entry/src/main/resources/rawfile 目录下会生成 bundle.harmony.js 和 assets 文件夹,assets 用来存放图片(如果 bundle 中不涉及本地图片,则没有 assets 文件夹)。

注意上面安装依赖若是版本不适配下面这条命令执行完之后是会报错的
执行代码npm run dev

运行成功之后AwesomeProject/harmony/entry/src/main/resources/rawfile 目录下会生成 bundle.harmony.js 和 assets 文件夹

三、创建鸿蒙工程

3.1在DevEco Studio新建工程

根据以下步骤操作

本次我的项目创建在了下面红色框的路径内

3.2添加 React Native 配置

在DevEco Studio中 entry 目录下执行以下命令:

ohpm i @rnoh/react-native-openharmony@0.72.x根据自己刚刚上面安装的依赖版本来,我的是0.72.90,所以执行ohpm i @rnoh/react-native-openharmony@0.72.90

红色框内命令执行完并成功后会工程级目录以及模块级目录下生成 oh_modules 文件夹。

3.3创建cpp文件夹

在src文件夹中的main目录新建一个cpp文件夹,分别存放CMakeLists.txt和PackageProvider.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)

PackageProvider.cpp文件内容如下:

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

3.4打开 MyApplicaton\entry\build-profile.json5,将 cpp 中的代码添加到应用工程的编译构建任务中

build-profile.json5文件内容如下:

{
  "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",
    }
  ]
}

3.5补充ArkTS侧的代码

修改红色框内文件EntryAbility.ets文件内容如下:

import { RNAbility } from '@rnoh/react-native-openharmony';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
 
const DOMAIN = 0x0000;
 
export default class EntryAbility extends RNAbility {
  getPagePath() {
    return 'pages/Index';
  }
 
  override onCreate(want: Want): void {
    super.onCreate(want);
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onCreate');
  }
 
  override onDestroy(): void {
    super.onDestroy();
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onDestroy');
  }
 
  override onWindowStageCreate(windowStage: window.WindowStage): void {
    super.onWindowStageCreate(windowStage);
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onWindowStageCreate');
  }
 
  override onWindowStageDestroy(): void {
    super.onWindowStageDestroy();
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onWindowStageDestroy');
  }
 
  override onForeground(): void {
    super.onForeground();
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onForeground');
  }
 
  override onBackground(): void {
    super.onBackground();
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'EntryAbility onBackground');
  }
}

3.6在 MyApplicaton\entry\src\main\ets 目录下新增 RNPackagesFactory.ets

该文件需要满足以下要求:

在 @rnoh/react-native-openharmony 导入 RNPackageContext 和 RNPackage;
在文件中导出 createRNPackages 方法,用于创建三方库或自定义 TurboModule、Fabric的package 对象。

红色框内文件内容如下:

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

3.7打开 MyApplicaton\entry\src\main\ets\pages\Index.ets,添加RNOH的使用代码

红色框内文件内容如下:

​
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 {
    // 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: { "foo": "bar" } as Record<string, string>,
          appKey: "AwesomeProject",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
          },
          jsBundleProvider: new TraceJSBundleProviderDecorator(
            new AnyJSBundleProvider([
              new MetroJSBundleProvider(),
              // NOTE: to load the bundle from file, place it in
              // `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`
              // on your device. The path mismatch is due to app sandboxing on OpenHarmony
              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%')
  }
}
 
​

3.8拷贝文件

AwesomeProject的文件。里面有两个文件:bundle.harmony.js文件和assets文件夹。(注意assets文件夹有两个,选择里面有三个文件那个),然后拷贝进去刚刚创建鸿蒙项目文件夹的rawfile文件夹下。拷贝完之后如下图所示

3.9运行项目

打开DevEco Studio按下面步骤进行操作

手机模拟器启动成功后

运行成功

Logo

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

更多推荐