一、创作背景
上一篇博客中,我给大家分享了怎样创建一个RN的项目,并且解决了其中的问题点,成功打出了Bundle包。接下来就是我给大家分享一下,怎样在原生鸿蒙项目中使用那个Bundle包,这一篇分享完才算是开发情况真正的搭建好了。
在本篇中,我将继续分享情况搭建中会遇到的坑点,帮助大家快速搭建成功。
二、搭建鸿蒙原生RN的原生项目部分
1、创建一个普通的鸿蒙原生项目
2、复制鸿蒙tgz包到项目中
在RN项目最外层新建2个文件夹,分别为react-native-harmony以及react-native-harmony-cli。然后将鸿蒙的相应这2个tgz包分别放入相应文件夹中,目录层级大概是如许子:
3、关联鸿蒙tgz文件
打开package.json,在dependencies中关联上前面新建的tgz包
4、关联openharmony包
在鸿蒙项目的根目录中,新建一个libs文件夹。
将官方提供的openharmony包复制进去,如下图。
接下来修改一下原生项目的oh-package.json文件,关联一下刚刚复制进去的openharmony包。
5、安装鸿蒙所需的依靠
打开命令行,进入原生项目的根目录,运行ohpm install命令。
如果报下面的错误,说明上一步,关联包有问题,找不到包:
如果安装依靠成功,命令行会是下面如许子:
此时进入鸿蒙原生项目中查看,会发现多了ohpm_module的文件夹:
6、补充C++侧代码
- 在 MyApplication/entry/src/main 目录下新建 cpp 文件夹。
- 在 cpp 目录下新增 CMakeLists.txt,并将 RNOH 的适配层代码添加到编译构建中天生 librnoh_app.so:
- project(rnapp)
- cmake_minimum_required(VERSION 3.4.1)
- set(CMAKE_SKIP_BUILD_RPATH TRUE)
- set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
- set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
- set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
- set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
- set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
- add_compile_definitions(WITH_HITRACE_SYSTRACE)
- set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
- add_subdirectory("${RNOH_CPP_DIR}" ./rn)
- add_library(rnoh_app SHARED
- "./PackageProvider.cpp"
- "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
- )
- target_link_libraries(rnoh_app PUBLIC rnoh)
复制代码 - 在 cpp 目录下新增 PackageProvider.cpp,将以下代码直接复制进去即可
- #include "RNOH/PackageProvider.h"
- using namespace rnoh;
- std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
- return {};
- }
复制代码 - 打开 MyApplicaton\entry\build-profile.json5,将以下代码直接复制进去即可:
- {
- "apiType": "stageMode",
- "buildOption": {
- + "externalNativeOptions": {
- + "path": "./src/main/cpp/CMakeLists.txt",
- + "arguments": "",
- + "cppFlags": "",
- + }
- },
- "buildOptionSet": [
- {
- "name": "release",
- "arkOptions": {
- "obfuscation": {
- "ruleOptions": {
- "enable": true,
- "files": [
- "./obfuscation-rules.txt"
- ]
- }
- }
- }
- },
- ],
- "targets": [
- {
- "name": "default"
- },
- {
- "name": "ohosTest",
- }
- ]
- }
复制代码 7、补充arkts侧代码
- 打开 MyApplicaton\entry\src\main\ets\entryability\EntryAbility.ets,之前默认是继承自UIAbility,这里要改成继承RNAbility。并且需要重写 getPagePath,返回程序的入口 page。
- import { RNAbility } from '@rnoh/react-native-openharmony';
- export default class EntryAbility extends RNAbility {
- getPagePath() {
- return 'pages/Index';
- }
- }
复制代码 - 在 MyApplicaton\entry\src\main\ets 目录下新增 RNPackagesFactory.ets,把以下代码复制进去即可:
- import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
- export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
- return [];
- }
复制代码 - 打开MyApplicaton\entry\src\main\ets\pages\Index.ets,添加RNOH的使用代码,修改后如下:
- import {
- AnyJSBundleProvider,
- ComponentBuilderContext,
- FileJSBundleProvider,
- MetroJSBundleProvider,
- ResourceJSBundleProvider,
- RNApp,
- RNOHErrorDialog,
- RNOHLogger,
- TraceJSBundleProviderDecorator,
- RNOHCoreContext
- } from '@rnoh/react-native-openharmony';
- import { createRNPackages } from '../RNPackagesFactory';
- @Builder
- export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}
- const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
- @Entry
- @Component
- struct Index {
- @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
- @State shouldShow: boolean = false
- private logger!: RNOHLogger
- aboutToAppear() {
- this.logger = this.rnohCoreContext!.logger.clone("Index")
- const stopTracing = this.logger.clone("aboutToAppear").startTracing();
- this.shouldShow = true
- stopTracing();
- }
- onBackPress(): boolean | undefined {
- // NOTE: this is required since `Ability`'s `onBackPressed` function always
- // terminates or puts the app in the background, but we want Ark to ignore it completely
- // when handled by RN
- this.rnohCoreContext!.dispatchBackPress()
- return true
- }
- build() {
- Column() {
- if (this.rnohCoreContext && this.shouldShow) {
- if (this.rnohCoreContext?.isDebugModeEnabled) {
- RNOHErrorDialog({ ctx: this.rnohCoreContext })
- }
- RNApp({
- rnInstanceConfig: {
- createRNPackages,
- enableNDKTextMeasuring: true, // 该项必须为true,用于开启NDK文本测算
- enableBackgroundExecutor: false,
- enableCAPIArchitecture: true, // 该项必须为true,用于开启CAPI
- arkTsComponentNames: []
- },
- initialProps: { "foo": "bar" } as Record<string, string>,
- appKey: "AwesomeProject",
- wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
- onSetUp: (rnInstance) => {
- rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
- },
- jsBundleProvider: new TraceJSBundleProviderDecorator(
- new AnyJSBundleProvider([
- new MetroJSBundleProvider(),
- // NOTE: to load the bundle from file, place it in
- // `/data/app/el2/100/base/com.rnoh.tester/files/bundle.harmony.js`
- // on your device. The path mismatch is due to app sandboxing on HarmonyOS
- new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
- new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
- new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
- ]),
- this.rnohCoreContext.logger),
- })
- }
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 8、复制RN天生的业务bundle到项目中
将之前RN那边天生的bundle 文件和 assets 图片放在 entry/src/main/resources/rawfile 路径下,由于上一步我们在代码中设置了从rawfile下面获取,以是就能加载到这个目录。
9、重新编译项目依靠
上面已经把鸿蒙的RN相干依靠都设置好了,接下来进入DevEco Studio,选择File->Sync and Refresh Project选项,编译器会把前面设置的依靠都加载进编译器的内存。
10、构建和运行项目
点击运行按钮即可。接下来就是摘取胜利果实的时候了,也是最容易出现问题的时候。我会将其中可能出现的问题,枚举出来分享出来给大家。
问题一 没有设置cmakelist
如果你没有设置cmakelist大概设置不正确,将会报如下错误:
解决方案:详见步调6,新建cpp文件,将设置代码复制进入即可。
问题二 项目路径太长
如果你的项目路径名字太长,获取文件夹放得太深,导致整个路径超过260个字符,也会编译不外,详细报错信息如下:
解决方案:将项目路径放浅一些,然后路径里每个文件夹名字都改简单一些。
问题三 Ability继承错误
你想使用RN的那个Ability需要继承自RNAbility,如果你忘记改了,继续继承UIAbility的话,那么就会报一下错误:
解决方案:参考步调7,修改继承的父类即可。
问题四 鸿蒙依靠错误
如果你的cpp情况没有设置好,大概是没有把包复制到前面说过的目录下,就会报这个错误:
解决方案:参考步调6,设置好cpp相干依靠。
问题五 官方DEMO方法名错误
如果你是直接下载的官方DEMO,运行的时候会报这个方法找不到的错误。
解决方案:这个是官方DEMO自带的问题,把报错的地方instance->callFunction改成instance->callJSFunction即可。
三、本文总结
在本文中,我分享了怎样搭建鸿蒙原生这边的情况,可以让RN那边打出来的bundle包跑起来。同时列出来了很多大家都很容易碰到的问题,并且给出了对应解决方案,希望能对大家有所帮助。
接下来,我将分享RN在鸿蒙端的热加载和调试设置,以及分享其中的踩坑点,感爱好的家人们可以点赞关注一下。文中有表达错误的地方,也欢迎大家品评指正,共同进步。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |