一、创作背景

上一篇博客中,我给大家分享了如何创建一个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++侧代码

  1. 在 MyApplication/entry/src/main 目录下新建 cpp 文件夹。
  2. 在 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)
     
  3. 在 cpp 目录下新增 PackageProvider.cpp,将以下代码直接复制进去即可
    #include "RNOH/PackageProvider.h"
    
    using namespace rnoh;
    
    std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {};
    }
     
  4. 打开 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侧代码

  1. 打开 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';
    }
    }
     
  2. 在 MyApplicaton\entry\src\main\ets 目录下新增 RNPackagesFactory.ets,把以下代码复制进去即可:
    import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
    export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
    return [];
    }
     
  3. 打开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在鸿蒙端的热加载和调试配置,以及分享其中的踩坑点,感兴趣的家人们可以点赞关注一下。文中有表达错误的地方,也欢迎大家批评指正,共同进步。

如何在原生鸿蒙APP中使用RN的bundle包的更多相关文章

  1. Hybrid App中原生页面 VS H5页面(分享)

    本文部分转自  http://www.jianshu.com/p/00ff5664e000 现有3类主流APP,分别为:Web App.Hybrid App(混合模式移动应用,Hybrid有“混合的” ...

  2. APICloud原生APP中ajax需要用api.ajax

    报错截屏: APICloud原生APP中ajax请求需要用api.ajax(api对象的ajax方法来替代),否则会将引起请求失败. APICloud api.ajax

  3. Hybrid App中原生页面 VS H5页面

    Hybrid App中原生页面 VS H5页面   现有3类主流APP,分别为:Web App.Hybrid App(混合模式移动应用,Hybrid有"混合的"意思). Nativ ...

  4. 分享 Ionic 开发 Hybrid App 中遇到的问题以及后期发布 iOS/Android 的方方面面

    此篇文章主要整理了最近在使用 Ionic 开发 Hybrid App 过程中遇到的一些疑难点以及后期发布生成 iOS 和 Android 版本过程中的种种问题. 文章目录 Ionic 简介和项目需求介 ...

  5. 去它的h5,我还是用js写原生跨平台app吧

    智能手机功能越来越强大,已经在逐渐替代电脑的作用.百度.腾讯.阿里的移动端日活数也在逐步的赶上甚至超越电脑端用户.叫喊着“mobile first”的公司越来越多,App开发者应运而生,且队伍日趋庞大 ...

  6. 总结XX网app中webapp常见的前端错误。

    在2016年12月至2017年1月,这一个月的时间内,我参与了易政网app中webapp前端项目的工作,下面将我在此次项目中犯的错误总结起来,以防下次再犯.也终于知道之前看的文章中的一段话所代表的意义 ...

  7. 在 ReactNative 的 App 中,集成 Bugly 你会遇到的一些坑

    一.前言 最近开新项目,准备尝试一下 ReactNative,所以前期做了一些调研工作,ReactNative 的优点非常的明显,可以做到跨平台,除了少部分 UI 效果可能需要对不同的平台进行单独适配 ...

  8. cocos2d-x在App中的应用

    cocos2d-x是一个应用广泛的开源游戏引擎,主要是应用与开发2D游戏,开源运行于多个平台,如果只是针对于移动端平台而言,可以运行于android和ios平台. cocos2d-x目前的版本是3.1 ...

  9. JSPatch 可以让你用 JavaScript 书写原生 iOS APP

    简介   JSPatch 可以让你用 JavaScript 书写原生 iOS APP.只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本 ...

  10. iClap分享:如何优雅的在 APP 中实现测试?

    开发团队常面临的问题有:内测 APP 时测出一堆 bug 写了很多文档,交到下一个人手中时问题总是不够清晰明了;版本发布公测时只能分发原生版本给团队和用户,无法快速反馈测试和体验结果;使用第三方工具, ...

随机推荐

  1. zabbix 二次开发(添加menu)

    zabbix 二次开发--- 在zabbix菜单栏中增加 CMDB 菜单,该菜单下有个子栏目 CMDB overview,如图: 实现此效果,我们需要修改两个地方:menu.inc.php 和 mai ...

  2. Ubuntu 配置默认编辑器

    在 Ubuntu 系统中,可以通过多种方式配置默认的文本编辑器,以便在使用命令行工具(如 crontab 或 visudo)时自动使用你喜欢的编辑器.以下是几种常见的方法: 使用 update-alt ...

  3. Navicat16 安装破解教程

    Navicat16 安装破解教程 Navicat 16.1 什么是Navicat? 官网下载Navicat 注册包的使用 Navicat 16.1 在文章最后添加工作号 回复关键词获取注册机 什么是N ...

  4. Android Studio 项目已经sync完成,但是在布局中显示:Design editor is unavaliable until after a sunncessful project sync

    原因:在drawable文件夹中新增了一个png图标 解决:同步在drawable-v24文件中复制一份即可

  5. PlugIR:开源还不用微调,首尔大学提出即插即用的多轮对话图文检索 | ACL 2024

    即插即用的PlugIR通过LLM提问者和用户之间的对话逐步改进文本查询以进行图像检索,然后利用LLM将对话转换为检索模型更易理解的格式(一句话).首先,通过重新构造对话形式上下文消除了在现有视觉对话数 ...

  6. 使用vue-cli4快速搭建项目环境、使用webpack4打包自己的library类库、封装vue插件并发布

    快速创建 使用官方推荐的vue-cli创建项目如下: # 安装 Vue Cli npm install -g @vue/cli # 创建一个项目 vue create vanttest # 创建完成后 ...

  7. CTC联结时间分类算法: 连接主义时间分类: 用递归神经网络标记未分割序列数据《Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks》(语音、文本识别、RNN端到端训练序列数据的方法)

    11月6号例会汇报. 糊弄的看了一个算法-CTC算法,没有汇报论文,因为没看论文(我导知道后,应该会锤死我...) 当然,汇报完之后,被我导腾讯会议通过网线批了我一顿,PPT做的太烂了!字太多,听不到 ...

  8. CSS – 实战 Color

    前言 之前 W3Schools 学习笔记 (1) 也记入过 Color, 这篇整理一下在网页开发中, 颜色是如果被处理的. 网页都有什么颜色? 网页篇幅最大的颜色, 通常是来自图片, 不管是背景图, ...

  9. CSS – Dimension min-content, max-content, fit-content

    前言 无意间在 practice 的时候看到视频使用, 以前没有听过. 它有点像 Figma 的 hug content, 据说 CSS 2.1 也是有类似的概念, 只是没有被正式纳入 CSS 里. ...

  10. @RestController和@Controller的区别

    @RestController 和 @Controller 是Spring框架中用于定义控制器(Controller)的两个非常重要的注解,它们都用于处理HTTP请求,但它们之间存在一些关键的区别. ...