RHOH启动流程

鸿蒙 RN 启动阶段分为 RN 容器创建、Worker 线程启动、NAPI 方法初始化、RN 实例创建四个阶段,接下来加载 bundle 和界面渲染,类图如下所示:

请添加图片描述

RN容器创建

  • EntryAbility

    全局 Ability,App 的启动入口。

  • Index.ets

    App 页面入口。

  • RNApp.ets

    • 配置 appKey,和 JS 侧 registerComponent 注册的 appKey 关联;
    • 配置初始化参数 initialProps,传递给 js 页面;
    • 配置 jsBundleProvider,指定 bundle 加载路径;
    • 配置ArkTS混合组件 wrappedCustomRNComponentBuilder
    • 配置 rnInstanceConfig,指定开发者自定义 package,注入字体文件 fontResourceByFontFamily,设置 BG 线程开关,设置 C-API 开关;
    • 持有 RNSurface,作为 RN 页面容器。
  • RNSurface.ets

    RN 页面容器,持有 ContentSlot 用于挂载 ArkUI 的 C-API 节点和响应手势事件。

Worker线程启动

TurboModule 运行在 worker 线程,worker 线程是在程序启动时创建。

  • WorkerThread.ts

    EntryAbility 创建时会创建 RNInstancesCoordinatorRNInstancesCoordinator 的构造函数中获取 worker 线程类地址,然后调用 WorkerThread 的 create 方法启动 worker 线程,如下:

    const workerThread = new WorkerThread(logger, new worker.ThreadWorker(scriptUrl, { name: name }), onWorkerError)
    
  • RNOHWorker.ets

    WorkerThread 中配置的 scriptUrlRNOHWorker.ets 路径,RNOHWorker.ets 内部调用 setRNOHWorker.etssetRNOHWorker 方法配置 worker 线程收发消息通道。

  • setRNOHWorker.ets

    setRNOHWorker 方法配置 worker 线程收发消息通道,createTurboModuleProvider 方法注册系统自带和开发者自定义的运行在 worker 线程的 TurboModule。

NAPI方法初始化

  • RNOHAppNapiBridge.cpp

    Init 方法是静态方法,在程序启动时调用,配置了 18 个 ArkTS 调用 C++ 的方法,如下:

    registerWorkerTurboModuleProvider,
    getNextRNInstanceId, 
    onCreateRNInstance,                  // 创建RN实例
    onDestroyRNInstance,                 // 销毁RN实例
    loadScript,                          // 加载bundle
    startSurface,
    stopSurface,
    destroySurface,
    createSurface,                       // 创建RN界面
    updateSurfaceConstraints,
    setSurfaceDisplayMode,
    onArkTSMessage,
    emitComponentEvent,                  // 给RN JS发消息
    callRNFunction, 
    onMemoryLevel,
    updateState,
    getInspectorWrapper,
    getNativeNodeIdByTag
    
  • NapiBridge.ts

    ArkTS 侧 RNInstance.tsSurfaceHandle.ts 调用 C++ 的桥梁。

RN实例创建

RNInstance.ts 中创建 RN 实例,分为以下步骤:

  1. 获取 RNInstance 的 id:在 RNInstanceRegistry.ets 中通过 NAPI 调用 getNextRNInstanceId 方法获取。
  2. 注册 ArkTS 侧 TurboModule:在 RNInstance.ts 中调用 processPackage 方法注册系统自带和开发者自定义的运行在 UI 线程上的 TurboModule。
  3. 注册字体:在 RNInstanceFactory.h 中调用 FontRegistry.hregisterFont 方法注册应用侧扩展字体,接着通过图形接口注入字体信息。
  4. 注册 RN 官方能力和开发者自定义能力:RNInstanceFactory.h 中通过 PackageProvider.cppgetPackage 方法获取 RN 系统自带和开发者自定义 TurboModule,接着注册系统 View、系统自带 TurboModule、开发者自定义 View、开发者自定义 TurboModule。
  5. 注册 ArkTS 混合组件:在 RNInstanceFactory.cpp 中注册 ArkTS 侧传递到 C++ 的 ArkTS 组件。
  6. 初始化 JS 引擎:在 RNInstanceInternal.cpp 中初始化 JS 引擎 Hermes 或者 JSVM,通过 JS 引擎驱动 JS 消息队列。
  7. 注册 TM 的 JSI 通道:在 RNInstanceCAPI.cpp 中调用 createTurboModuleProvider 创建 TurboModuleProvider,注入 __turboModuleProxy 对象给 JS 侧。
  8. 注入 Scheduler:在 RNInstanceInternal.cpp 中初始化 Fabric 的 Scheduler 对象,ReactCommon 的组件绘制找到鸿蒙适配层注入的 SchedulerDelegate 才能进行界面绘制。
  9. 注册 Fabric 的 JSI 通道:在 RNInstanceInternal.cpp 中调用 UIManagerBinding.cppcreateAndInstallIfNeeded 方法注入 nativeFabricUIManager 对象给 JS 侧。

加载bundle

RN 实例创建完毕则开始加载 bundle,如下:

ArkTS 侧加载 bundle、C++ 侧加载 bundle,切线程到 ReactCommon 的 Instance.cpp 中加载 bundle:

RNApp.ets > RNInstance.ts > RNOHAppNapiBridge.cpp > RNInstanceInternal.cpp > Instance.cpp

打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

在这里插入图片描述

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

在这里插入图片描述

最后运行效果图如下显示:

在这里插入图片描述

在这里插入图片描述

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐