鸿蒙环境添加React Native的bundle包

文章目录

一、创建HarmonyOS工程

二、添加 React Native 配置

在刚创建的HarmonyOS工程的entry(D:\RN\MyRNApplication\entry>)目录下执行命令:

复制代码
ohpm i @rnoh/react-native-openharmony

执行完成后会在工程级目录以及模块级目录下生成 oh_modules 文件夹。

三、在HarmonyOS工程中集成RNOH

1.补充CPP侧代码 在 RNApplication\entry\src\main目录下新建cpp文件夹,并新增CMakeLists.txt文件:

将 RNOH 的适配层代码添加到CMakeLists.txt中用于编译生成librnoh_app.so,例如将以下代码复制到新创建的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)

2.在cpp 目录下新增 PackageProvider.cpp并复制以下代码。

复制代码
#include "RNOH/PackageProvider.h"

using namespace rnoh;

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

3.打开 RNApplication\entry\build-profile.json5,将 cpp 中的代码添加到应用工程的编译构建任务中。 如果在 x86_64 架构的模拟器上运行应用,需在 externalNativeOptions 配置中额外添加 abiFilters 字段,并包含 x86_64 架构参数。 如下所示,abiFilters 字段当前被注释,默认仅构建适用于 arm64-v8a 架构的版本。详细介绍可以参考模块级build-profile.json5。

复制代码
{
 "apiType": "stageMode",
 "buildOption": {
+   "externalNativeOptions": {
+      "path": "./src/main/cpp/CMakeLists.txt",
+      "arguments": "",
+      "cppFlags": "",
+      // "abiFilters": ["arm64-v8a", "x86_64"]
+    }
 },
 "targets": [
   {
     "name": "default"
   },
   {
     "name": "ohosTest",
   }
 ]
}
  1. 补充ArkTS侧的代码 打开 RNApplication\entry\src\main\ets\entryability\EntryAbility.ets,替换为如下代码。

    import { RNAbility } from '@rnoh/react-native-openharmony';
    import { hilog } from '@kit.PerformanceAnalysisKit';

    export default class EntryAbility extends RNAbility {
    getPagePath() {
    return 'pages/Index';
    }

    override onCreate(want: Want): void {
    super.onCreate(want);
    hilog.info(0x0000, 'testTag', '%{public}s', 'EntryAbility onCreate');
    }
    }

5.在 RNApplication\entry\src\main\ets 目录下新增 RNPackagesFactory.ets, 复制如下代码。

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

6.打开 MyRNApplication\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%')
  }
}

RNApp的参数appKey需要与RN工程中AppRegistry.registerComponent注册的appName保持一致,否则会导致白屏。

四、加载bundle包

本地加载 bundle。将RNProject\harmony\entry\src\main\resources\rawfile目录下的 bundle 文件和 assets 文件夹粘贴复制到HarmonyOS工程RNApplication\entry\src\main\resources\rawfile路径下,在 entry/src/main/ets/pages/Index.ets 中使用。

五、启动并运行工程

使用 DevEco Studio 运行 RNApplication 工程。如果运行按钮灰色不可用,需要先执行file->sync and refresh project。 执行完成后,控制台如图所示:

首次运行耗时可能需要10分钟左右,请耐心等待。

相关推荐
贾伟康19 小时前
HarmonyOS API 26 Navigation 跨包路由:router_map、HSP 按需加载与失败回落
harmonyos·arkts·模块化·navigation·hsp
KevinChaos19 小时前
阳台小花园开发手记 04|HarmonyOS 7.0 互动卡片:倾斜手机时的卡片效果
华为·harmonyos
威哥爱编程1 天前
模拟面试智能体开发实战 04:面试聊到哪算哪?用状态机把整场面试编排起来
python·agent·harmonyos
威哥爱编程1 天前
模拟面试智能体开发实战 03:AI 面试官太客气?人设 Prompt 让它像个真考官
python·agent·harmonyos
贾伟康1 天前
HarmonyOS API 26 Navigation 导航栏位置:navBarPosition、左右布局与折叠屏适配
harmonyos·arkts·arkui·navigation·折叠屏
贾伟康2 天前
HarmonyOS API 26 DevEco Code 需求到 ArkTS 骨架的提示词分层
harmonyos·arkts·ai coding·deveco code·工程提效
Highcharts.js2 天前
Highcharts Orbit 完全指南:把每一张图表变成交互式分析工具
react.js·前端框架·highcharts·orbit·使用指南·ai 图表·交互式分析工具
威哥爱编程2 天前
模拟面试智能体开发实战 02:回答等半分钟,谁还愿意练?把服务端和流式输出搭起来
python·agent·harmonyos
威哥爱编程2 天前
模拟面试智能体开发实战 01:面试挂了都不知道挂在哪?用 Python 给自己造一个随叫随到的 AI 面试官
python·agent·harmonyos
贾伟康2 天前
HarmonyOS API 26 HMAF Skill 可解释任务计划与失败回退
harmonyos·arkts·智能体·skill·hmaf