HarmonyOS 鸿蒙Next中RN一些三方库是不是不需要codegen也可以使用?

HarmonyOS 鸿蒙Next中RN一些三方库是不是不需要codegen也可以使用? 如题,比如AsyncStorage

3 回复

你好,并非所有RN三方库都需要通过Codegen生成桥接代码,具体可参考RN三方库使用情况说明中的三方库是否已适配Codegen,如已适配Codegen,在使用前需要主动执行生成三方库桥接代码,详细请参考Codegen使用文档

相关知识:如何使用CodeGen生成粘合代码来实现RN自定义HarmonyOS组件

【问题描述】

如何使用CodeGen生成粘合代码来实现RN自定义HarmonyOS组件

【背景知识】

RN自定义HarmonyOS组件:React Native for OpenHarmony(RNOH)是基于React Native 0.75版本适配支持的,可以使用Fabric来实现RN应用工程加载或引用到HarmonyOS开发的自定义组件。

CodeGen:会根据JavaScript接口描述文件创建C++粘合代码,用于将部分组件逻辑(比如调用HarmonyOS平台接口能力)与React Native结合起来。

【解决方案】

实现步骤如下,分为RN工程实现步骤、HarmonyOS工程步骤以及RN工程引用自定义组件。

1、RN工程步骤

1.1 JavaScript接口描述文件:自定义组件以及组件参数
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'

import type { ViewProps } from 'react-native';

interface NativeProps extends ViewProps {}

export default codegenNativeComponent<NativeProps>('OhosCompView');
1.2 Codegen配置

在RN工程package.json中新增codegenConfig配置,用于指定生成粘合代码的目录。

"harmony": {
  "alias": "rtn-turboModuleSpce",
  "codegenConfig": [
    {
      "version": 1,
      "specPaths": [
        "./src/specs"
      ]
    }
  ]
}

alias:模块的别名。

codegenConfig:存放要生成的第三方库的对象数组,每个对象又包含两个字段:

version:Codegen版本,取值:{1,2},1表示为arkts组件。

specPaths:JavaScript接口描述文件的相对路径

在RN工程中配置CodeGen脚本命令,指定胶水代码生成目录。

{
  "name": "MyApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    ...
    "codegen": "react-native codegen-harmony --cpp-output-path ./entry/src/main/cpp/generated --rnoh-module-path ./entry/oh_modules/@rnoh/react-native-openharmony"
  },
  ...
}

2、HarmonyOS 工程步骤

2.1 实现HarmonyOS自定义组件
import { Descriptor, RNOHContext, RNViewBase, ViewBaseProps } from "@rnoh/react-native-openharmony";

export interface OhosCompViewProps extends ViewBaseProps{}

export type OhosCompViewDescriptor = Descriptor<"OhosCompView", OhosCompViewProps>

@Component
export struct OhosCompView {

  @State private descriptor: OhosCompViewDescriptor = {} as OhosCompViewDescriptor

  static NAME: string = "OhosCompView"

  ctx!: RNOHContext

  tag: number = 0

  aboutToAppear(): void {
    this.descriptor = this.ctx.descriptorRegistry.getDescriptor<OhosCompViewDescriptor>(this.tag)
    // 当RN侧传递过来的属性参数发生变化时,我们需要更新Descripotor
    this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag, (newDescriptor) => {
      this.descriptor = (newDescriptor as OhosCompViewDescriptor)
    })
  }

  build() {
    RNViewBase({ ctx: this.ctx, tag: this.tag}) {
      RelativeContainer() {
        Text("Hello World")
          .id('OhosCompView')
          .fontSize('50fp')
          .fontWeight(FontWeight.Bold)
          .alignRules({
            center: { anchor: '__container__', align: VerticalAlign.Center },
            middle: { anchor: '__container__', align: HorizontalAlign.Center }
          })
      }
    }
    .height("100%")
    .width("100%")
  }
}

Descriptor的功能是封装RN侧组件代码传递到ArkUI组件的参数。在沒有参数时,也需要封装Descriptor,否则启动时会异常报错。

  • 组件内容需在RNViewBase内,即作为RNViewBase的子组件。
2.2 在Index的buildCustomRNComponent中新增自定义组件

创建RNComponentContext时,传入wrappedCustomRNComponentBuilder用于构建加载HarmonyOS组件。

import { OhosCompView } from '../specView/OhosCompView'

@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
  if (ctx.componentName === OhosCompView.NAME) {
    OhosCompView({
      ctx: ctx.rnComponentContext,
      tag: ctx.tag
    })
  }
}

const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
2.3 在RNApp的rnInstanceConfig中增加OhosCompView.NAME配置

配置HarmonyOS自定义组件的名称。

RNApp({
  rnInstanceConfig: {
    createRNPackages,
    enableNDKTextMeasuring: true, // 该项必须为true,用于开启NDK文本测算
    enableBackgroundExecutor: false,
    enableCAPIArchitecture: true, // 该项必须为true,用于开启CAPI
    arkTsComponentNames: [OhosCompView.NAME] // 增加OhosCompView.NAME配置
  },
  ...
})
2.4 在PackageProvider.cpp中引入依赖

在RNOHGeneratedPackage.h中有自定义组件与JSIBinder对应关系,需在PackageProvider中引入。

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"

using namespace rnoh;

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

3、RN工程中使用自定义组件

在使用自定义组件时,需在Rn页面中定义HarmonyOS自定义组件的高度。

import React from 'react';
import {
  ScrollView,
  View,
} from 'react-native';
import OhosCompView from './src/native/OhosCompNativeComponent'

function App(): JSX.Element {
  return (
    <ScrollView>
      <View>
        <OhosCompView style={{height: 400}}/>
      </View>
    </ScrollView>
  );
}

export default App;

更多关于HarmonyOS 鸿蒙Next中RN一些三方库是不是不需要codegen也可以使用?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中,部分React Native三方库确实可以不依赖codegen直接使用。这主要取决于库是否采用了新架构的TurboModule规范。传统非TurboModule库仍可通过JS层调用,但性能可能受限。对于纯JS实现的逻辑库(如lodash),codegen完全不需要。涉及原生能力的库若未强制codegen配置,在Next的兼容模式下也可能直接运行。需注意,不使用codegen可能导致类型安全检查缺失。

在HarmonyOS Next中,确实有一些React Native (RN) 的三方库(如 AsyncStorage)不需要 codegen 也能正常使用。这类库通常属于纯 JavaScript 实现的模块,不涉及原生平台 (Java/ObjC) 的代码生成。

具体来说:

  1. AsyncStorage 这类纯 JS 实现的存储库,其功能完全通过 RN 的 JS 层 API 实现,不依赖原生模块,因此不需要 codegen 处理。
  2. 但如果是包含原生代码的 RN 库(如需要调用 HarmonyOS 原生能力的模块),则仍然需要通过 codegen 生成对应的原生接口代码。
  3. 建议在使用前查看库的文档说明,确认其是否依赖原生模块实现。

对于 AsyncStorage 这类纯 JS 库,在 HarmonyOS Next 中可以像在标准 RN 环境中一样直接引入使用。

回到顶部