ReactNative鸿蒙化从底子到应用

打印 上一主题 下一主题

主题 1842|帖子 1842|积分 5526

准备:

下载node.js:Node.js — 在任何地方运行 JavaScript
下载完成后一直点下一步继续安装完成。
安装完成后,在终端输入:node -v 查看node版本
                                            npm -v 查看npm版本

下载安装React Native:搭建开发环境 · React Native 中文网 
在终端输入:npm install -g expo-cli
安装DevEco Studio,其中DevEco Studio的api版本要大于13
文档中央
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-software-install-V5

环境配置:


官方文档地址:GitCode - 全球开发者的开源社区,开源代码托管平台

windows 环境变量设置方法:

hdc环境配置

hdc 是 OpenHarmony 为开发职员提供的用于调试的命令行工具,鸿蒙 React Native 工程利用 hdc 进行真机调试。hdc 工具通过 OpenHarmony SDK 获取,存放于 SDK 的 toolchains 目次下,请将 {DevEco Studio安装路径}/sdk/{SDK版本}/openharmony/toolchains 的完整路径添加到环境变量中。
a. 在此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,编辑系统变量path,添加hdc工具路径。
b. 在此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,添加 HDC 端口变量名为:HDC_SERVER_PORT,变量值可设置为恣意未被占用的端口,如 7035。


安装an zan文档中央配置 CAPI 版本环境变量


当前RN框架提供的 Demo 工程默认为 CAPI 版本,您需要配置环境变量 RNOH_C_API_ARCH = 1。


  • Windows 环境:
    此电脑 > 属性 > 高级系统设置 > 高级 > 环境变量中,在系统变量中点击新建,添加变量名为:RNOH_C_API_ARCH,变量值为 1。

Mac环境配置: 

终端输入:open ~/.zshrc

假如没有.zshrc文件,输入vim ~/.zshrc 创建环境配置文件。
创建新项目React Native侧:

终端输入:npx react-native@0.72.5 init AwesomeProject --version 0.72.5 --skip-install 

打开工程的package.json文件,在 scripts 下新增 OpenHarmony 的依靠


终端进入AwesomeProject目次,并运行安装依靠包命令:npm i @react-native-oh/react-native-harmony@0.72.53

安装完成:

1.打开 AwsomeProject\metro.config.js,并添加 OpenHarmony 的适配代码。配置文件的详细先容,可以参考React Native 中文网。修改完成后的文件内容如下:

全部删掉,替换成:
  1. const {mergeConfig, getDefaultConfig} = require('@react-native/metro-config');
  2. const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');
  3. /**
  4. * @type {import("metro-config").ConfigT}
  5. */
  6. const config = {
  7.   transformer: {
  8.     getTransformOptions: async () => ({
  9.       transform: {
  10.         experimentalImportSupport: false,
  11.         inlineRequires: true,
  12.       },
  13.     }),
  14.   },
  15. };
  16. module.exports = mergeConfig(getDefaultConfig(__dirname), createHarmonyMetroConfig({
  17.   reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
  18. }), config);
复制代码

2.在 AwesomeProject 目次下运行天生 bundle 文件的命令。运行成功后,会在 AwesomeProject/harmony/entry/src/main/resources/rawfile 目次下天生 bundle.harmony.js 和 assets 文件夹,assets 用来存放图片(假如 bundle 中不涉及本舆图片,则没有 assets 文件夹)。 
在RN的终端输入:npm run dev

鸿蒙侧: 

只支持api13的工程项目:

创建完成后,进入entry目次的终端:

终端输入:ohpm i @rnoh/react-native-openharmony@0.72.53

在原生工程中集成RNOH


1.补充CPP侧代码


  • 在 MyApplication/entry/src/main 目次下新建 cpp 文件夹。
  • 在 cpp 目次下新增 CMakeLists.txt,并将 RNOH 的适配层代码添加到编译构建中天生 librnoh_app.so:
  1. project(rnapp)
  2. cmake_minimum_required(VERSION 3.4.1)
  3. set(CMAKE_SKIP_BUILD_RPATH TRUE)
  4. set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
  5. set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
  6. set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
  7. set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
  8. set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
  9. set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
  10. add_compile_definitions(WITH_HITRACE_SYSTRACE)
  11. set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
  12. add_subdirectory("${RNOH_CPP_DIR}" ./rn)
  13. add_library(rnoh_app SHARED
  14.     "./PackageProvider.cpp"
  15.     "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
  16. )
  17. target_link_libraries(rnoh_app PUBLIC rnoh)
复制代码
2.在 cpp 目次下新增 PackageProvider.cpp,该文件需要满足以下要求:


  • 需要导入 RNOH/PackageProvider;
  • 实现 getPackages 方法,用于创建三方库或自界说 TurboModule 或 Fabric 的 package 对象。
   此处不涉及三方库与自界说 TurboModule 或组件,需要返回空数组。
  
  1. #include "RNOH/PackageProvider.h"
  2. using namespace rnoh;
  3. std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
  4.     return {};
  5. }
复制代码
 3.打开 MyApplicaton\entry\build-profile.json5,将 cpp 中的代码添加到鸿蒙的编译构建使命中,详细先容可以参考模块级build-profile.json5:
  1. "buildOption": {
  2.     "externalNativeOptions": {
  3.            "path": "./src/main/cpp/CMakeLists.txt",
  4.            "arguments": "",
  5.            "cppFlags": "",
  6.         }
  7.   },
复制代码

补充ArkTS侧的代码


  • 打开 MyApplicaton\entry\src\main\ets\entryability\EntryAbility.ets,引入并利用 RNAbility,该文件需要满足以下的要求:

    • 假如需要扩展利用对应的生命周期函数,请在代码中利用 super,RNAbility 在生命周期函数中进行了对应的利用,需要利用 super 保证功能不丢失;
    • 需要重写 getPagePath,返回步伐的入口 page。


  1. import { RNAbility } from '@rnoh/react-native-openharmony';
  2. export default class EntryAbility extends RNAbility {
  3.   getPagePath() {
  4.     return 'pages/Index';
  5.   }
  6. }
复制代码
2.在 MyApplicaton\entry\src\main\ets 目次下新增 RNPackagesFactory.ets,该文件需要满足以下要求:


  • 在 @rnoh/react-native-openharmony 导入 RNPackageContext 和 RNPackage;
  • 在文件中导出 createRNPackages 方法,用于创建三方库或自界说 TurboModule、Fabric的package 对象。
   此处不涉及三方库与自界说TurboModule或组件,需要返回空数组。
  
  1. import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
  2. export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  3.   return [];
  4. }
复制代码
3.打开 MyApplicaton\entry\src\main\ets\pages\Index.ets,添加RNOH的利用代码,修改后如下:
   RNApp的参数appKey需要与RN工程中AppRegistry.registerComponent注册的appName保持同等,否则会导致白屏。
  1. import {
  2.   AnyJSBundleProvider,
  3.   ComponentBuilderContext,
  4.   FileJSBundleProvider,
  5.   MetroJSBundleProvider,
  6.   ResourceJSBundleProvider,
  7.   RNApp,
  8.   RNOHErrorDialog,
  9.   RNOHLogger,
  10.   TraceJSBundleProviderDecorator,
  11.   RNOHCoreContext
  12. } from '@rnoh/react-native-openharmony';
  13. import { createRNPackages } from '../RNPackagesFactory';
  14. @Builder
  15. export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}
  16. const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
  17. @Entry
  18. @Component
  19. struct Index {
  20.   @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
  21.   @State shouldShow: boolean = false
  22.   private logger!: RNOHLogger
  23.   aboutToAppear() {
  24.     this.logger = this.rnohCoreContext!.logger.clone("Index")
  25.     const stopTracing = this.logger.clone("aboutToAppear").startTracing();
  26.     this.shouldShow = true
  27.     stopTracing();
  28.   }
  29.   onBackPress(): boolean | undefined {
  30.     // NOTE: this is required since `Ability`'s `onBackPressed` function always
  31.     // terminates or puts the app in the background, but we want Ark to ignore it completely
  32.     // when handled by RN
  33.     this.rnohCoreContext!.dispatchBackPress()
  34.     return true
  35.   }
  36.   build() {
  37.     Column() {
  38.       if (this.rnohCoreContext && this.shouldShow) {
  39.         if (this.rnohCoreContext?.isDebugModeEnabled) {
  40.           RNOHErrorDialog({ ctx: this.rnohCoreContext })
  41.         }
  42.         RNApp({
  43.           rnInstanceConfig: {
  44.             createRNPackages,
  45.             enableNDKTextMeasuring: true, // 该项必须为true,用于开启NDK文本测算
  46.             enableBackgroundExecutor: false,
  47.             enableCAPIArchitecture: true, // 该项必须为true,用于开启CAPI
  48.             arkTsComponentNames: []
  49.           },
  50.           initialProps: { "foo": "bar" } as Record<string, string>,
  51.           appKey: "AwesomeProject",
  52.           wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
  53.           onSetUp: (rnInstance) => {
  54.             rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
  55.           },
  56.           jsBundleProvider: new TraceJSBundleProviderDecorator(
  57.             new AnyJSBundleProvider([
  58.               new MetroJSBundleProvider(),
  59.               // NOTE: to load the bundle from file, place it in
  60.               // `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`
  61.               // on your device. The path mismatch is due to app sandboxing on OpenHarmony
  62.               new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
  63.               new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
  64.               new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
  65.             ]),
  66.             this.rnohCoreContext.logger),
  67.         })
  68.       }
  69.     }
  70.     .height('100%')
  71.     .width('100%')
  72.   }
  73. }
复制代码
最后:加载bundle包 

将RN侧的rawfile文件拷贝到鸿蒙侧的rawfile

 

 鸿蒙侧运行:

热更新:




熟悉React Native 

React Native 是由 Facebook 开发的一个开源框架,用于构建原生移动应用。它联合了 React 的声明式编程范式和 JavaScript 的机动性,答应开发者利用相同的代码库为 iOS 和 Android 平台创建高性能、美观且用户体验良好的应用。
总之,React Native 是一个强盛的跨平台移动应用开发框架,恰当各种规模和类型的项目。假如你想快速开发高性能的移动应用,React Native 是一个不错的选择。
底子知识:

   组件先容:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表