设置自定义TurboModule运行在worker线程

  1. CalculatorModule 的基类从 UITurboModule 改为 AnyThreadTurboModule
    // entry/src/main/ets/turbomodule/CalculatorModule.ts
    import { AnyThreadTurboModule, UITurboModule } from '@rnoh/react-native-openharmony/ts';
    import { TM } from '@rnoh/react-native-openharmony/generated/ts';
    
    export class CalculatorModule extends AnyThreadTurboModule implements TM.RTNCalculator.Spec {
      add(a: number, b: number): Promise<number>{
        return Promise.resolve(a+b);
      }
    }
    
  2. 将重写的父类方法从 getUITurboModuleFactoryByNameMap()createEagerUITurboModuleByNameMap() 分别换成 getAnyThreadTurboModuleFactoryByNameMap()createEagerAnyThreadTurboModuleByNameMap()
    // entry/src/main/ets/GeneratedPackage.ets
    import {
      RNOHPackage,
      AnyThreadTurboModule,
      AnyThreadTurboModuleContext,
      UITurboModule,
      UITurboModuleContext
    } from '@rnoh/react-native-openharmony';
    
    import { TM } from "@rnoh/react-native-openharmony/generated"
    import { CalculatorModule } from './turbomodule/CalculatorModule';
    
    export default class GeneratedPackage extends RNOHPackage {
      override getAnyThreadTurboModuleFactoryByNameMap(): Map<string, (ctx: AnyThreadTurboModuleContext) => AnyThreadTurboModule | null> {
        return new Map<string, ((ctx: AnyThreadTurboModuleContext) => AnyThreadTurboModule)>()
          .set(TM.RTNCalculator.NAME, (ctx) => new CalculatorModule(ctx))
      }
    
      override async createEagerAnyThreadTurboModuleByNameMap(ctx: AnyThreadTurboModuleContext): Promise<Map<string, AnyThreadTurboModule>> {
        const calculatorModule = new CalculatorModule(ctx);
        return new Map()
          .set(TM.RTNCalculator.NAME, calculatorModule)
      }
    }
    
  3. 配置TurboModule运行在worker线程,需要继承RNability后重载 getRNOHWorkerScriptUrl ,代码修改方式如下所示:
    // entry/src/main/ets/entryability/EntryAbility.ets
    import {RNAbility} from '@rnoh/react-native-openharmony';
    
    export default class EntryAbility extends RNAbility {
    +  override getRNOHWorkerScriptUrl() {
    +    return "entry/ets/workers/RNOHWorker.ets"
    +  }
    ...
    }
    

在ets路径下右击,选择 New 选项,右侧展开菜单选择 Woker 选项:
请添加图片描述

选择后在弹出的窗口中取名 RNOHWorker.ets
请添加图片描述

此时目录结构为:

└── ets
    ├── entryability
    ├── page
    ├── rn
    └── workers
        └── RNOHWorker.ets         

开发中,当需要开启 Worker 线程以优化 React Native 应用性能时,需通过 RNOHWorker.ets 配置 Worker 线程的核心参数。以下是完整的配置代码及参数说明,包含可选的 HttpClient 自定义与 caPathProvider 证书路径规则配置,并明确线程间配置的独立性及 rnInstanceName 的使用方式。


在鸿蒙(HarmonyOS)开发中,如果你想在自定义的 TurboModule 中运行代码,特别是在 worker 线程中,你需要遵循一些特定的步骤和考虑一些问题。TurboModules 是 React Native 用于提高性能和模块化的一部分,而鸿蒙操作系统是基于 Android 的,因此很多 React Native 的实践可以借鉴。

  1. 创建自定义 TurboModule

首先,确保你的项目中已经集成了 React Native。然后,你可以按照以下步骤创建一个自定义 TurboModule:

1.1 创建 TurboModule 类

在你的 React Native 项目中,创建一个新的 C++ 文件(例如 MyTurboModule.cpp),并继承自 facebook::react::TurboModule

include <ReactCommon/TurboModule.h>
include <jsi/jsi.h>

namespace facebook {
namespace react {

class MyTurboModule : public TurboModule {
public:
    static const char* const kJSIMethodName = "MyTurboModule";
    static const char* const kJSIName = "MyTurboModule";

    MyTurboModule(CallInvokerInvoker callInvoker) : TurboModule(callInvoker) {}

    // 实现你的方法
    void myMethod(double value) {
        // 实现你的逻辑
    }
};

} // namespace react
} // namespace facebook

1.2 在 CMakeLists.txt 中添加模块

确保你的 CMakeLists.txt 文件包含了你的模块:

add_library(myturbomodule SHARED MyTurboModule.cpp)
target_link_libraries(myturbomodule PUBLIC react_codegen_rncore)
  1. 在 JavaScript 中使用 TurboModule

在 JavaScript 端,你需要生成一个桥接代码来调用你的 C++ 方法:

import { NativeModules } from 'react-native';

const { MyTurboModule } = NativeModules;
MyTurboModule.myMethod(10);
  1. 在 Worker 线程中运行 TurboModule 方法

要在 worker 线程中运行,你需要使用 React Native 的 Worker API 或者其他线程管理库。例如,使用 Worker API:

3.1 创建 Worker 脚本

首先,创建一个 worker 脚本文件(例如 WorkerScript.js):

self.onmessage = (event) => {
    const { data } = event; // 从主线程接收数据
    NativeModules.MyTurboModule.myMethod(data); // 调用你的 TurboModule 方法
    self.postMessage('Processed'); // 向主线程发送消息
};

3.2 在主线程中使用 Worker

在你的主线程 JavaScript 文件中:

import Worker from 'react-native-worker'; // 确保已安装 react-native-worker 或其他合适的库来创建 Worker。
import { NativeModules } from 'react-native';

const worker = new Worker('./WorkerScript.js'); // 创建 Worker 实例
worker.postMessage(10); // 向 Worker 发送数据
worker.onmessage = (event) => {
    console.log(event.data); // 处理 Worker 发回的消息
};
  1. 编译和运行你的应用
    确保你的所有更改都已正确编译,并在设备或模拟器上运行你的应用。检查是否有任何错误或性能问题。如果遇到问题,可以查看日志调试问题。

  2. 注意事项和最佳实践:

  • 线程安全:确保你的 TurboModule 方法是线程安全的,特别是当它们被多个线程调用时。React Native 的桥接层通常不是线程安全的,因此需要谨慎处理。
  • 性能优化:在多线程环境中运行代码时,注意性能和资源管理。避免不必要的阻塞或资源竞争。
  • 错误处理:在多线程环境中添加适当的错误处理和异常捕获逻辑。

通过上述步骤,你应该能够在鸿蒙(HarmonyOS)上使用 React Native 的自定义 TurboModule 在 worker 线程中运行代码。


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

Logo

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

更多推荐