diff --git a/zh-cn/fabric.md b/zh-cn/fabric.md index 2b0431c83bff603fc4302cb38da01e7e504dfc3f..73c8f5c051277cdbae57b92e19ef48e68e2ddff7 100644 --- a/zh-cn/fabric.md +++ b/zh-cn/fabric.md @@ -18,6 +18,8 @@ Fabric 组件是一种使用 Fabric 渲染器渲染并展示在屏幕上的 UI 接下来会创建一个简单的名为 `RTNCenteredText` 的 Fabric 组件作为示例。 +**该示例仅提供 HarmonyOS 版本,Android/iOS 版本请阅读 React-Native 官方文档的 [Fabric 组件章节](https://reactnative.cn/docs/the-new-architecture/pillars-fabric-components)** + ## 目录配置 同样的,我们按照一般的三方库目录结构来配置: @@ -26,8 +28,8 @@ Fabric 组件是一种使用 Fabric 渲染器渲染并展示在屏幕上的 UI . ├── MyApp └── RTNCenteredText - ├── android(Android 的原生实现代码) - ├── ios(iOS 的原生实现代码) + ├── android(Android 的原生实现代码,若有) + ├── ios(iOS 的原生实现代码,若有) ├── harmony(HarmonyOS 的原生实现代码) └── src (js/ts代码) ``` @@ -60,7 +62,7 @@ import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNati type NativeProps = $ReadOnly<{| ...ViewProps, text: ?string, - // add other props here + // 在这里添加其他属性 |}>; export default (codegenNativeComponent( @@ -99,9 +101,9 @@ export default codegenNativeComponent( ### 2. Codegen 配置 -#### Shared +#### 2.1 配置 `package.json` 文件 -shared 是 package.json 文件中的一个配置项,它将在 yarn/npm 安装模块时被调用。请在 `RTNCenteredText` 的根目录创建 `package.json` 文件。 +请在 `RTNCenteredText` 的根目录创建 `package.json` 文件。 ```json { @@ -112,12 +114,7 @@ shared 是 package.json 文件中的一个配置项,它将在 yarn/npm 安装 "source": "src/index", "files": [ "src", - "android", - "ios", "harmony", - "rtn-centered-text.podspec", - "!android/build", - "!ios/build", "!**/__tests__", "!**/__fixtures__", "!**/__mocks__" @@ -135,161 +132,55 @@ shared 是 package.json 文件中的一个配置项,它将在 yarn/npm 安装 "react": "*", "react-native": "*" }, - "harmony": { - "codegenConfig": { - "specPaths": [ - "./src" - ] - } - }, - "codegenConfig": { - "name": "RTNCenteredTextSpecs", - "type": "components", - "jsSrcsDir": "src" - } } ``` -将 Codegen 的配置声明到 codegenConfig 字段。codegenConfig 是一个用于存放要生成的第三方库的对象数组,每个对象又包含其它三个字段: - -- name:第三方库的名称。按照惯例,名称应以 Spec 为结尾 -- type:在这个 npm 包里的模块类型。在本例中,我们开发的是 Turbo Native Module,所以值为 modules -- jsSrcsDir:用于找到 js 接口声明文件的相对路径,它将被 Codegen 解析 - -#### Android - -若要在 Android 平台运行 Codegen,需要创建三个文件: -1. 带有 Codegen 配置信息的 build.gradle 文件 -2. AndroidManifest.xml -3. 一个实现 ReactPackage 接口的 Java 类 -在文件创建完成后,`android` 目录文件结构应该是这样的: +#### 2.2 选择 Fabric 的原生实现方式,配置 codegen -```md -android -├── build.gradle -└── src - └── main - ├── AndroidManifest.xml - └── java - └── com - └── rtncenteredtext - └── RTNCenteredTextPackage.java -``` - -首先,在 `android` 目录创建 `build.gradle` 文件,并配置以下内容: +RNOH 有特殊的架构限制,需要开发者在开发前根据需求选择好使用 ArkTS API 还是 CAPI 实现 Fabric。 -**build.gradle** - - +关于如何选择,请阅读这篇[说明文档](https://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/capi-architecture.md)。 -#### **build.gradle** +此步操作是要将 Codegen 的配置声明到 harmony.codegenConfig 字段。 -```gradle -buildscript { - ext.safeExtGet = {prop, fallback -> - rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback - } - repositories { - google() - gradlePluginPortal() - } - dependencies { - classpath("com.android.tools.build:gradle:7.1.1") - } -} +- version: 枚举值,1 代表ArkTS组件的codegen版本,2 代表CAPI组件的codegen版本;(关于ArkTS和CAPI组件请见2.2的详细说明) +- specPaths:用于找到 js 接口声明文件的相对路径,它将被 Codegen 解析 -apply plugin: 'com.android.library' -apply plugin: 'com.facebook.react' +> [!WARNING] 接入 codegen 之后,同一个模块中 ArkTS 版本和 CAPI 版本的 Fabric 无法共存,请先选择好实现方式 -android { - compileSdkVersion safeExtGet('compileSdkVersion', 31) +在 `package.json` 中新增 harmony.codegenConfig 字段: - defaultConfig { - minSdkVersion safeExtGet('minSdkVersion', 21) - targetSdkVersion safeExtGet('targetSdkVersion', 31) - buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true") - } -} +##### Option1: HarmonyOS (ArkTS Fabric) -repositories { - maven { - // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url "$projectDir/../node_modules/react-native/android" +```json +{ + // ... + "harmony": { + "codegenConfig": { + "version": 1, + "specPaths": ["./src"], + } } - mavenCentral() - google() -} - -dependencies { - implementation 'com.facebook.react:react-native:+' } ``` - - -其次,创建 `android/src/main` 目录,然后在这个目录内创建 `AndroidManifest.xml` 文件,并编写以下代码: - - +##### Option2: HarmonyOS (CAPI Fabric) -#### **AndroidManifest.xml** - -```xml - - -``` - - - -这个 manifest 文件的用途是声明您开发的模块的 Java 包 - -最后,您需要一个继承 TurboReactPackage 接口的类。在运行 Codegen 前,您不用完整实现这个类。对于 App 而言,一个没有实现接口的空类就已经能当做一个 React Native 依赖,Codegen 会尝试生成其脚手架代码。 - -创建 `android/src/main/java/com/rtncenteredtext` 目录,在这个目录内创建 `RTNCenteredTextPackage.java` 文件 - -**RTNCenteredTextPackage.java** - - - -#### **RTNCenteredTextPackage.java** - -```java -package com.rtncenteredtext; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; - -import java.util.Collections; -import java.util.List; - -public class RTNCenteredTextPackage implements ReactPackage { - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - return Collections.emptyList(); +```json +{ + // ... + "harmony": { + "codegenConfig": { + "version": 2, + "specPaths": ["./src"], } - + } } ``` - - -ReactPackage 接口的用途是让 React Native 为使用 App 中的 ViewManager 和 Native Modules,识别出哪些原生类需要在第三方库里导出。 - -Codegen 会在 App 编译的时候自动运行。 - -#### HarmonyOS (ArkTS Fabric) - -> [!WARNING] 接入 codegen 之后,同一个模块中 ArkTS 版本和 CAPI 版本的 Fabric 无法共存,请先选择好实现方式 +##### 2.3 codegen通用配置项 HarmonyOS 需要在 RN 工程中通过运行脚本来执行 Codegen。 @@ -308,376 +199,15 @@ HarmonyOS 需要在 RN 工程中通过运行脚本来执行 Codegen。 > codegen-harmony 参数介绍: -1. --rnoh-module-path: 指定 @rnoh/react-native-openharmony 模块的相对路径,用于存储生成的 ts 文件;如果使用 har 包引入 rnoh 模块,则需要指向:./harmony/entry/oh_modules/@rnoh/react-native-openharmony" +1. --rnoh-module-path: 指定 @rnoh/react-native-openharmony 模块的相对路径,用于存储生成的 ts 文件;如果使用 har 包引入 RNOH SDK,则需要指向安装之后的路径,比如:./harmony/entry/oh_modules/@rnoh/react-native-openharmony" 2. --cpp-output-path: 指定用于存储生成的 C++ 文件的输出目录的相对路径,默认 ./harmony/entry/src/main/cpp/generated; 3. --project-root-path: 包根目录的相对路径。 -#### HarmonyOS (CAPI Fabric) - -> [!WARNING] 接入 codegen 之后,同一个模块中 ArkTS 版本和 CAPI 版本的 Fabric 无法共存,请先选择好实现方式 - -目前 Codegen 暂时不支持构造 CAPI 版本的 Fabric 模块,,所以我们需要手动运行 Android 的 Codegen,然后把生成的代码复制过来使用。 - -> [!WARNING] 请务必先把 Android 的 Codegen 配置好再执行以下操作 - -删除 package.json 中的 harmony.codegenConfig 字段 - -```diff -{ - ... - "harmony": { -- "codegenConfig": { -- "specPaths": [ -- "./src" -- ] -- } - }, -} -``` - -首先我们需要一个 React-Native App 来执行 Codegen,假设 App 的目录是和 当前目录平级的 `MyApp`,执行以下命令来创建一个 Gradle 任务来执行 Codegen。 - -> [!tip] 在运行 Codegen 之前,您需要在 Android 中的 App 启动新架构。您可以通过修改 gradle.properties 文件中的 newArchEnabled 属性,将 false 改为 true。 - -```bash -// 进入模块工程 -cd RTNCenteredText - -// 打包模块 -npm pack - -// 进入 App 工程 -cd ../MyApp - -// 本地路径安装模块 -npm i file:../RTNCenteredText/rtn-centered-text-0.0.1.tgz - -cd android - -./gradlew generateCodegenArtifactsFromSchema -``` - -生成后的代码保存在 `MyApp/node_modules/rtn-centered-text/android/build/generated/source/codegen` 目录,并呈以下结构: - -```md -codegen -├── java -│ └── com -│ └── facebook -│ └── react -│ └── viewmanagers -│ ├── RTNCenteredTextManagerDelegate.java -│ └── RTNCenteredTextManagerInterface.java -├── jni -│ ├── Android.mk -│ ├── CMakeLists.txt -│ ├── RTNCenteredText-generated.cpp -│ ├── RTNCenteredText.h -│ └── react -│ └── renderer -│ └── components -│ └── RTNCenteredText -│ ├── ComponentDescriptors.h -│ ├── EventEmitters.cpp -│ ├── EventEmitters.h -│ ├── Props.cpp -│ ├── Props.h -│ ├── RTNCenteredTextSpecsJSI-generated.cpp -│ ├── RTNCenteredTextSpecsJSI.h -│ ├── ShadowNodes.cpp -│ ├── ShadowNodes.h -│ ├── States.cpp -│ └── States.h -└── schema.json -``` - -`codegen/jni/react/renderer/components/RTNCenteredText` 目录下的代码是 HarmonyOS 需要的。(RTNCenteredTextSpecsJSI-generated.cpp、RTNCenteredTextSpecsJSI.h除外) +### 3. 实现原生组件 -将这些代码文件复制到 `harmony/rtn-centered-text/src/main/cpp` 文件夹下,并 **修改一下各文件 "include" 的路径**。 - -如 `ComponentDescriptor.h` - -```diff -... -- #include -+ #include "ShadowNodes.h" -#include -... -``` - -然后在同级目录创建 `CMakeLists.txt`,`RTNCenteredTextJSIBinder.h`,`RTNCenteredTextPackage.h`,目录结构如下 - -```md -harmony -└── rtn-centered-text - ├── src - │ └── main - │ ├── cpp - │ │ ├── CMakeLists.txt - │ │ ├── ComponentDescriptors.h - │ │ ├── EventEmitters.cpp - │ │ ├── EventEmitters.h - │ │ ├── Props.cpp - │ │ ├── Props.h - │ │ ├── ShadowNodes.cpp - │ │ ├── ShadowNodes.h - │ │ ├── States.cpp - │ │ ├── States.h - │ │ ├── RTNCenteredTextJSIBinder.h - │ │ └── RTNCenteredTextPackage.h - │ └── modules.json5 - ├── build-profile.json5 - ├── hvigorfile.ts - └── oh-package.json5 -``` - - - -#### **CMakeLists.txt** - -```c -# the minimum version of CMake -cmake_minimum_required(VERSION 3.13) -set(CMAKE_VERBOSE_MAKEFILE on) - -file(GLOB rtn_centered_text_SRC CONFIGURE_DEPENDS *.cpp) -add_library(rtn_centered_text SHARED ${rtn_centered_text_SRC}) -target_include_directories(rtn_centered_text PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(rtn_centered_text PUBLIC rnoh) -``` - - - - - -#### **RTNCenteredTextJSIBinder.h** - -```cpp -#include "RNOHCorePackage/ComponentBinders/ViewComponentJSIBinder.h" - -namespace rnoh { - -class RTNCenteredTextJSIBinder : public ViewComponentJSIBinder { - facebook::jsi::Object createNativeProps(facebook::jsi::Runtime &rt) override { - auto object = ViewComponentJSIBinder::createNativeProps(rt); - object.setProperty(rt, "text", "string"); - return object; - } -}; -} // namespace rnoh -``` - - - -JSI Binder 的作用是桥接 JS 和 C++,将属性从 JS 端传递到 C++ 端。 - - - - - -#### **RTNCenteredTextPackage.h** - -```cpp -#include "RNOH/Package.h" -#include "ComponentDescriptors.h" -#include "RTNCenteredTextJSIBinder.h" - -namespace rnoh { - -class RTNCenteredTextPackage : public Package { -public: - CenteredTextPackage(Package::Context ctx): Package(ctx) {} - - std::vector createComponentDescriptorProviders() override { - return {facebook::react::concreteComponentDescriptorProvider()}; - } - - ComponentJSIBinderByString createComponentJSIBinderByName() override { - return {{"RTNCenteredText", std::make_shared()}}; - } -}; -} // namespace rnoh -``` - - - -Package 接口的用途是让 React-Native 识别出三方库需要导出哪些 C++ 接口。 - -### 3. 原生代码 - -#### Android - -Android 平台中 Fabric 组件的原生代码必须包含以下三个部分: - -1. RTNCenteredText.java 用于渲染原生视图 -2. RTNCenteredTextManager.java 用于实例化原生视图 -3. 在 RTNCenteredTextPackage.java 实现具体的逻辑代码 - -Android 第三方库目录文件结构应为如下: - -```md -android -├── build.gradle -└── src - └── main - ├── AndroidManifest.xml - └── java - └── com - └── rtncenteredtext - ├── RTNCenteredText.java - ├── RTNCenteredTextManager.java - └── RTNCenteredTextPackage.java -``` - - - -#### **RTNCenteredText.java** - -```java -package com.rtncenteredtext; - -import androidx.annotation.Nullable; -import android.content.Context; -import android.util.AttributeSet; -import android.graphics.Color; - -import android.widget.TextView; -import android.view.Gravity; - -public class RTNCenteredText extends TextView { - - public RTNCenteredText(Context context) { - super(context); - this.configureComponent(); - } - - public RTNCenteredText(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - this.configureComponent(); - } - - public RTNCenteredText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.configureComponent(); - } - - private void configureComponent() { - this.setBackgroundColor(Color.RED); - this.setGravity(Gravity.CENTER_HORIZONTAL); - } -} -``` - - - -这个类表示的是原生视图,将由 Android 渲染到屏幕上。它继承了 TextView 并且调用私有方法 configureComponent() 来配置自身的基本参数。 - - - -#### **RTNCenteredTextManager.java** - -```java -package com.rtncenteredtext; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.SimpleViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewManagerDelegate; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.viewmanagers.RTNCenteredTextManagerInterface; -import com.facebook.react.viewmanagers.RTNCenteredTextManagerDelegate; - - -@ReactModule(name = RTNCenteredTextManager.NAME) -public class RTNCenteredTextManager extends SimpleViewManager - implements RTNCenteredTextManagerInterface { - - private final ViewManagerDelegate mDelegate; - - static final String NAME = "RTNCenteredText"; - - public RTNCenteredTextManager(ReactApplicationContext context) { - mDelegate = new RTNCenteredTextManagerDelegate<>(this); - } - - @Nullable - @Override - protected ViewManagerDelegate getDelegate() { - return mDelegate; - } - - @NonNull - @Override - public String getName() { - return RTNCenteredTextManager.NAME; - } - - @NonNull - @Override - protected RTNCenteredText createViewInstance(@NonNull ThemedReactContext context) { - return new RTNCenteredText(context); - } - - @Override - @ReactProp(name = "text") - public void setText(RTNCenteredText view, @Nullable String text) { - view.setText(text); - } -} -``` - - - -RTNCenteredTextManager 类用于让 React Native 实例化原生组件,它实现了由 Codegen 生成的接口(见 implements 语句的 RTNCenteredTextManagerInterface 接口)并使用了 RTNCenteredTextManagerDelegate 类。 - -它同时负责导出所有 React Native 所需的内容,例如使用 @ReactModule 注解的 RTNCenteredTextManager 类,及使用 @ReactProp 注解的 setText 方法。 - -**RTNCenteredText.java** - -最后,打开 `android/src/main/java/com/rtncenteredtext` 目录的 `RTNCenteredTextPackage.java`,并进行以下修改: - - - -#### **RTNCenteredTextPackage update** - -```diff -package com.rtncenteredtext; - -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.ViewManager; - -import java.util.Collections; -import java.util.List; - -public class RTNCenteredTextPackage implements ReactPackage { - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { -+ return Collections.singletonList(new RTNCenteredTextManager(reactContext));; - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } - -} -``` - - - -新增的代码实例化了一个 RTNCenteredTextManager 对象,用于让 React Natve 运行时渲染 Fabric 组件。 - -#### HarmonyOS (ArkTS Fabric) +#### 3.1 Option1: 使用 ArkTS API 实现原生组件 HarmonyOS 平台中 ArkTS 版本的 Fabric 组件的原生代码必须包含以下三个部分: @@ -730,6 +260,7 @@ export struct RTNCenteredText { this.cleanUpCallbacks.push(this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag, (_descriptor, newDescriptorWrapper) => { this.onDescriptorWrapperChange(newDescriptorWrapper! as RNC.RTNCenteredText.DescriptorWrapper) + // 组件属性更新时进入的回调 } )) } @@ -756,27 +287,29 @@ export struct RTNCenteredText { - #### **RTNCenteredPackage.ts** ```ts -import { RNPackage } from '@rnoh/react-native-openharmony/ts'; +import { RNPackage } from "@rnoh/react-native-openharmony/ts"; import type { DescriptorWrapperFactoryByDescriptorTypeCtx, - DescriptorWrapperFactoryByDescriptorType -} from '@rnoh/react-native-openharmony/ts'; -import { RNC } from "@rnoh/react-native-openharmony/generated/ts" + DescriptorWrapperFactoryByDescriptorType, +} from "@rnoh/react-native-openharmony/ts"; +// import codegen 生成的内容 +import { RNC } from "@rnoh/react-native-openharmony/generated/ts"; export class RTNCenteredTextPackage extends RNPackage { - createDescriptorWrapperFactoryByDescriptorType(ctx: DescriptorWrapperFactoryByDescriptorTypeCtx): DescriptorWrapperFactoryByDescriptorType { + createDescriptorWrapperFactoryByDescriptorType( + ctx: DescriptorWrapperFactoryByDescriptorTypeCtx + ): DescriptorWrapperFactoryByDescriptorType { return { - [RNC.RTNCenteredText.NAME]: (ctx) => new RNC.RTNCenteredText.DescriptorWrapper(ctx.descriptor) - } + [RNC.RTNCenteredText.NAME]: (ctx) => + new RNC.RTNCenteredText.DescriptorWrapper(ctx.descriptor), + }; } } - ``` @@ -806,12 +339,12 @@ export * from "./src/main/ets/RTNCenteredText"; -#### HarmonyOS (CAPI Fabric) +#### 3.2 Option2: 使用 C-API 实现原生组件 -HarmonyOS 平台中 CAPI 版本的 Fabric 组件的原生代码必须包含以下部分: +HarmonyOS 平台中 C-API 版本的 Fabric 组件的原生代码必须包含以下部分: 1. 创建用于实现组件的 RTNCenteredTextComponentInstance.h、RTNCenteredTextComponentInstance.cpp; -2. 创建用于对接 ArkUI的 xxxNode.h、xxxNode.cpp;(若框架已经实现相关的Node,此步可以跳过。本例中需要用到的 TextNode、StackNode 框架已经实现,故无需自行创建) +2. 创建用于对接 ArkUI 的 xxxNode.h、xxxNode.cpp;(若框架已经实现相关的 Node,此步可以跳过。本例中需要用到的 TextNode、StackNode 框架已经实现,故无需自行创建) 3. Cpp 脚手架(请看 codegen 章节) 4. 修改 oh-package.json5,hvigorfile.ts,module.json5 @@ -881,6 +414,7 @@ protected: #### **RTNCenteredTextComponentInstance.cpp** + ```cpp #include "RTNCenteredTextComponentInstance.h" @@ -913,6 +447,7 @@ void RTNCenteredTextComponentInstance::onPropsChanged(SharedConcreteProps const #### **RTNCenteredTextPackage.cpp** + ```cpp #include "RNOH/Package.h" #include "ComponentDescriptors.h" @@ -954,7 +489,7 @@ public: -#### HarmonyOS (ArkTS Fabric 和 CAPI Fabric 共有部分) +#### 3.3 ArkTS Fabric 和 C-API Fabric 共有部分 修改 `oh-package.json5`,`hvigorfile.ts`,`module.json5`,或自行创建 @@ -966,8 +501,7 @@ public: { "license": "ISC", "types": "", - "devDependencies": { - }, + "devDependencies": {}, "name": "rtn-centered-text", "description": "", "main": "index.ets", @@ -976,7 +510,6 @@ public: "@rnoh/react-native-openharmony": "file:../react_native_openharmony" } } - ``` @@ -997,20 +530,19 @@ export { harTasks } from "@ohos/hvigor-ohos-plugin"; ```json { - module: { - name: 'centered_text', - type: 'har', - deviceTypes: ['default'], - }, + "module": { + "name": "centered_text", + "type": "har", + "deviceTypes": ["default"] + } } - ``` -### 5. 将 Fabric 组件添加到 App +### 4. 将 Fabric 组件添加到 App -#### Shared +#### 4.1 配置 RN 工程,执行 codegen 首先,需要将包含模块的 NPM 包添加到 App。请确保 package.json 已经配置安装好以下依赖: @@ -1018,7 +550,7 @@ export { harTasks } from "@ohos/hvigor-ohos-plugin"; { ... "dependencies": { - "react-native-harmony": "版本 >= 0.72.15", + "react-native-harmony": "x.x.x", ... }, "overrides": { @@ -1043,7 +575,7 @@ cd ../MyApp // 本地路径安装模块 npm i file:../RTNCenteredText/rtn-centered-text-0.0.1.tgz -// 执行以下命令执行 codegen (HarmonyOS ArkTS Fabric only) +// 执行以下命令执行 codegen npm run codegen @@ -1051,14 +583,7 @@ npm run codegen 此命令会将 RTNCenteredText 模块添加到 App 内的 node_modules 目录。 -#### Android - -在配置 Android 之前,您需要先开启新架构: - -1. 打开 android/gradle.properties; -2. 滑到文件底部,将 newArchEnabled 的值从 false 修改为 true。 - -#### HarmonyOS(ArkTS Fabric 和 CAPI Fabric 共有部分) +### 4.2 原生工程配置项 > [!tip] 待完善能力:HarmonyOS 平台目前暂时不支持 AutoLink,所以需要自行配置。 @@ -1082,13 +607,23 @@ npm run codegen ] } ``` -##### 引入原生端代码 + +在工程根目录的 `MyApp/harmony/oh-package.json5` 添加 overrides 字段 + +```json +{ + ... + "overrides": { + "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // RNOH SDK har包路径或源码路径 + } +} +``` 打开 `MyApp/harmony/entry/oh-package.json5`,添加以下依赖,引入鸿蒙原生端的代码 ```json "dependencies": { - "@rnoh/react-native-openharmony": "file:../react_native_openharmony", + "@rnoh/react-native-openharmony": "file:../react_native_openharmony.har", // RNOH SDK har包路径或源码路径 "rtn-centered-text": "file:../../node_modules/RTNCenteredText/harmony/rtn-centered-text" } ``` @@ -1100,7 +635,7 @@ cd entry ohpm install ``` -#### HarmonyOS(ArkTS Fabric) +#### 4.2.1 ArkTS 组件特有配置项 打开 `MyApp/harmony/entry/src/main/ets/pages/Index.ets`,添加: @@ -1108,38 +643,31 @@ ohpm install ... + import { RTNCenteredText } from "rtn-centered-text" ++ const arkTsComponentNames: Array = [RTNCenteredText.NAME]; @Builder export function buildCustomRNComponent(ctx: ComponentBuilderContext) { Stack() { - if (ctx.componentName === SampleView.NAME) { - SampleView({ - ctx: ctx.rnComponentContext, - tag: ctx.tag, - }) - } -+ else if (ctx.componentName === RTNCenteredText。NAME) { -+ RTNCenteredText({ -+ ctx: ctx.rnComponentContext, ++ if (ctx.componentName === RTNCenteredText.NAME) { ++ RTNCenteredText({ + tag: ctx.tag, ++ ctx: ctx.rnComponentContext, + }) + } - ... + //... } .position({x: 0, y: 0}) } -... +//... ``` 打开 `MyApp/harmony/entry/src/main/ets/RNPackageFactory.ts`,添加: ```diff import type {RNPackageContext, RNPackage} from '@rnoh/react-native-openharmony/ts'; -import {SamplePackage} from 'rnoh-sample-package/ts'; + import { RTNCenteredTextPackage } from "rtn-centered-text/ts"; export function createRNPackages(ctx: RNPackageContext): RNPackage[] { return [ - new SamplePackage(ctx), + new RTNCenteredTextPackage(ctx), ]; } @@ -1147,7 +675,7 @@ export function createRNPackages(ctx: RNPackageContext): RNPackage[] { 编译、运行即可。 -#### HarmonyOS(CAPI Fabric) +#### 4.2.1 C-API 组件特有配置项 打开 `MyApp/harmony/entry/src/main/cpp/CMakeLists.txt`,添加: @@ -1157,7 +685,7 @@ cmake_minimum_required(VERSION 3.4.1) set(CMAKE_SKIP_BUILD_RPATH TRUE) set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules") -+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") ++ set(OH_MODULES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules") set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp") set(LOG_VERBOSITY_LEVEL 1) set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments") @@ -1169,7 +697,7 @@ add_subdirectory("${RNOH_CPP_DIR}" ./rn) # RNOH_BEGIN: manual_package_linking_1 add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package) -+ add_subdirectory("${OH_MODULES}/rtn-centered-text-capi/src/main/cpp" ./centered-text) ++ add_subdirectory("${OH_MODULES_DIR}/rtn-centered-text-capi/src/main/cpp" ./centered-text) # RNOH_END: manual_package_linking_1 file(GLOB GENERATED_CPP_FILES "./generated/*.cpp") @@ -1207,7 +735,7 @@ std::vector> PackageProvider::getPackages(Package::Cont 编译、运行即可。 -#### JavaScript +### 4.3 JavaScript 最后,操作以下步骤,您就可以在 JavaScript 调用组件了。 @@ -1233,10 +761,10 @@ import RTNCenteredText from "rtn-centered-text/src/RTNCenteredTextNativeComponen * @format * @flow strict-local */ -import React from 'react'; -import type {Node} from 'react'; -import {SafeAreaView} from 'react-native'; -import RTNCenteredText from 'rtn-centered-text/src/RTNCenteredTextNativeComponent'; +import React from "react"; +import type { Node } from "react"; +import { SafeAreaView } from "react-native"; +import RTNCenteredText from "rtn-centered-text/src/RTNCenteredTextNativeComponent"; const App: () => Node = () => { // ... other App code ... @@ -1244,7 +772,7 @@ const App: () => Node = () => { ); @@ -1254,3 +782,5 @@ export default App; ``` + +现在,您可以运行 App 并查看在屏幕上显示的组件。