HarmonyOS 鸿蒙Next中RN一些三方库是不是不需要codegen也可以使用?
HarmonyOS 鸿蒙Next中RN一些三方库是不是不需要codegen也可以使用? 如题,比如AsyncStorage
你好,并非所有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) 的代码生成。
具体来说:
- AsyncStorage 这类纯 JS 实现的存储库,其功能完全通过 RN 的 JS 层 API 实现,不依赖原生模块,因此不需要 codegen 处理。
- 但如果是包含原生代码的 RN 库(如需要调用 HarmonyOS 原生能力的模块),则仍然需要通过 codegen 生成对应的原生接口代码。
- 建议在使用前查看库的文档说明,确认其是否依赖原生模块实现。
对于 AsyncStorage 这类纯 JS 库,在 HarmonyOS Next 中可以像在标准 RN 环境中一样直接引入使用。