



























环境:
node -> v18.16.0
DevEco Studio -> Build Version: 6.0.0.878
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
、
我这里选的是 0.72.86 版本
3)、打开rn项目在目录下的 package.json,在 scripts 下新增 OpenHarmony 的依赖:
"harmony": "react-native bundle-harmony --dev"
如下图

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 文件 ,保存好这俩个文件 呆会需要把他们拷贝到 鸿蒙工程项目下使用
1)、创建鸿蒙工

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)、在编辑器上 点击同步

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%') } }
1)、把第一步rn生成的 bundle.harmony.js 和 assets 文件 拷贝到 鸿蒙工程目录下的 项目/entry/src/main/resources/rawfile 文件夹 下面

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

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。