找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1186

积分

0

好友

210

主题
发表于 3 天前 | 查看: 7| 回复: 0

在鸿蒙原生应用(ArkUI)中集成 React Native 页面,是实现跨平台混合开发的高效手段。本文将以一个航班页面为例,详细介绍如何通过 MultiBundle 加载方案实现 React Native 页面的动态加载与路由跳转。本文涉及的核心技术栈包括 React-Native 跨端框架与鸿蒙 ArkUI 声明式开发。

首先,我们来看鸿蒙端承载 React Native 页面的核心组件 Flight.ets。这是一个基于 @rnoh/react-native-openharmony SDK 构建的页面级组件。

import {
  RNApp,
  RNOHErrorDialog,
  RNOHLogger,
  RNOHCoreContext,
  RNInstance,
  ResourceJSBundleProvider
} from '@rnoh/react-native-openharmony';
import { RNInstanceManager } from "../rn/RNInstanceManager";
import { buildCustomRNComponent } from "../rn/CustomRNComponent";

const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent);

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

  async aboutToAppear() {
    this.logger = this.rnohCoreContext!.logger.clone("Flight");
    const stopTracing = this.logger.clone("aboutToAppear").startTracing();
    this.rnInstance = await RNInstanceManager.getInstance("Flight");
    this.shouldShow = true;
    stopTracing();
  }

  onBackPress(): boolean | undefined {
    this.rnohCoreContext!.dispatchBackPress();
    return true;
  }

  build() {
    Column() {
      if (this.rnohCoreContext && this.shouldShow) {
        if (this.rnohCoreContext?.isDebugModeEnabled) {
          RNOHErrorDialog({ ctx: this.rnohCoreContext });
        }
        RNApp({
          rnInstanceConfig: {
            rnInstance: this.rnInstance as RNInstance,
          },
          initialProps: { "foo": "bar" } as Record<string, string>,
          appKey: "flight",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP");
          },
          jsBundleProvider: new ResourceJSBundleProvider(
            this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle/cp/flight.harmony.bundle')
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

核心代码解析

1. 组件生命周期与状态管理
  • aboutToAppear:此异步生命周期函数负责页面初始化。它通过 RNInstanceManager 按名称(”Flight”)获取对应的 React Native 实例,并进行性能追踪。准备好后,将 shouldShow 状态置为 true,触发 UI 渲染。
  • onBackPress:重写了物理返回键事件,将其转发给 React Native 上下文处理,确保导航栈行为一致。
  • @StorageLink@StaternohCoreContext 通过 @StorageLink 与全局应用存储绑定,用于共享核心上下文;shouldShow 是组件内部状态,控制 RNApp 的渲染时机。
2. RNApp 容器配置

RNApp 是渲染 React Native 内容的核心容器,其配置项是关键:

  • rnInstance:传入管理好的 React Native 运行时实例。
  • appKey:必须与 React Native 项目中注册的组件名称(如 AppRegistry.registerComponent(‘flight’, ...))完全一致。
  • jsBundleProvider:指定了 JavaScript 代码包的加载来源。此处使用 ResourceJSBundleProvider 从鸿蒙应用的 resources/rawfile 目录下加载名为 flight.harmony.bundle 的独立 Bundle 文件,这正是 MultiBundle 方案的核心——每个业务页面可以拥有独立的 Bundle。
3. 调试与错误处理

在调试模式下,RNOHErrorDialog 组件会被渲染,它可以捕获并展示 React Native 运行时的红屏错误,极大提升开发体验。

代码片段:指定独立Bundle路径
上图为配置独立 Bundle 路径的代码截图:bundle(‘cp/flight.harmony.bundle’)

打包与加载流程

  1. 打包 React Native 代码:在 React Native 项目中,通过 npm run harmony 等定制命令,将航班页面的相关代码打包成独立的 flight.harmony.bundle 文件。
  2. 集成至鸿蒙项目:将生成的 Bundle 文件放置于鸿蒙工程的 resources/rawfile/bundle/cp/ 目录下,作为应用资源。
  3. 动态加载:当导航到航班页面时,ResourceJSBundleProvider 会动态加载该路径下的 Bundle 文件,并交由 RNApp 容器解析执行。

命令行打包过程
执行 npm run harmony 命令,使用 Metro 打包器生成鸿蒙可用的 Bundle 文件。

打包成功输出
打包成功后的终端输出,显示 Metro 版本及构建完成信息。

方案优势与总结

通过上述 MultiBundle 方案,我们实现了:

  • 业务解耦:航班、酒店等不同业务模块的代码可分别打包,独立维护和更新。
  • 按需加载:只有在访问特定页面时才加载对应的 Bundle,优化应用启动速度和内存占用。
  • 原生融合:充分利用了鸿蒙 ArkUI 的声明式 UI 能力和系统特性,同时复用了 React Native 的跨端业务逻辑。

该方案非常适合大型跨平台应用,在保持 TypeScript 开发效率的同时,实现了更精细化的性能和资源管理。

航班页面最终效果
最终实现效果:在鸿蒙应用中成功加载并运行独立的 React Native 航班页面 Bundle。




上一篇:C语言双向链表作业实现与GDB调试实战指南
下一篇:2025年论文降AI率工具推荐:5款免费工具实测与选择指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 20:13 , Processed in 0.107417 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表