鸿蒙RN三方库使用AutoLinking
鸿蒙RN三方库使用AutoLinking
一、创建三方库工程
mkdir ~/react_native/example/rn-lib-math
cd ~/react_native/example/rn-lib-math
npm init .
初始化后得到一个基本的package.json文件,然后修改内容为:
{
"name": "rn-lib-math",
"version": "1.0.0",
"description": "rn lib math package of autolinking in harmony",
"main": "index.ts",
"scripts": {
"codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name rn-lib-math --cpp-output-path ./harmony/library/src/main/cpp/generated --ets-output-path ./harmony/library/src/main/ets/generated --cpp-components-spec-paths ./src/specs/cpp-components --turbo-modules-spec-paths ./src/specs/turbo-modules --arkts-components-spec-paths ./src/specs/arkts-components"
},
"author": "",
"license": "ISC",
"harmony": {
"alias": "rn-lib-math",
"autolinking": {
"cmakeLibraryTargetName": "rn_lib_math"
}
},
"files": [
"index.ts",
"src/*",
"harmony/*"
],
"dependencies": {},
"devDependencies": {
"@react-native-community/cli": "15.0.1",
"@react-native-oh/react-native-harmony": "^0.77.18",
"@react-native-oh/react-native-harmony-cli": "^0.77.18",
"@types/react": "^18.3.1",
"react": "18.3.1",
"react-native": "0.77.1"
}
}
写好package.json后 安装依赖,会产生node_modules目录
npm i —verbose
这里主要是
scripts里面的 codegen-lib配置
codegen-lib-harmony 跟codegen-harmony类似,只不过这里是针对lib库的代码生成,里面有几个路径要配置下
--npm-package-name rn-lib-math
--cpp-output-path ./harmony/library/src/main/cpp/generated
--ets-output-path ./harmony/library/src/main/ets/generated
--cpp-components-spec-paths ./src/specs/cpp-components
--turbo-modules-spec-paths ./src/specs/turbo-modules
--arkts-components-spec-paths ./src/specs/arkts-components
harmony配置
"harmony": {
"alias": "rn-lib-math",
"autolinking": {
"cmakeLibraryTargetName": "rn_lib_math"
}
},
files配置
"files": [
"index.ts",
"src/*",
"harmony/*"
],
devDependencies配置
"devDependencies": {
"@react-native-community/cli": "15.0.1",
"@react-native-oh/react-native-harmony": "^0.77.18",
"@react-native-oh/react-native-harmony-cli": "^0.77.18",
"@types/react": "^18.3.1",
"react": "18.3.1",
"react-native": "0.77.1"
}
创建TurboModule描述文件,arkts-components、cpp-components这两个目录先为空
src/specs/turbo-modules/MathModule.ts
import { TurboModule, TurboModuleRegistry } from "react-native";
export interface Spec extends TurboModule {
add(a: number, b: number): Promise<number>;
subtract(a: number, b: number): Promise<number>;
multiply(a: number, b: number): Promise<number>;
divide(a: number, b: number): Promise<number>;
}
export default TurboModuleRegistry.get<Spec>("MathModule");
二、创建harmony工程
用DevEco Studio 在当前路径下创建一个harmony工程,默认带一个entry模块,并且在harmony工程创建一个library模块(Static Library)
整体目录结构为,我们只需要用到里面library库
fangzhen@Mac rn-lib-math % tree -L 3 --gitignore
.
├── harmony
│ ├── AppScope
│ │ ├── app.json5
│ │ └── resources
│ ├── build-profile.json5
│ ├── code-linter.json5
│ ├── entry
│ │ ├── build-profile.json5
│ │ ├── hvigorfile.ts
│ │ ├── obfuscation-rules.txt
│ │ ├── oh-package-lock.json5
│ │ ├── oh-package.json5
│ │ └── src
│ ├── hvigor
│ │ └── hvigor-config.json5
│ ├── hvigorfile.ts
│ ├── library
│ │ ├── BuildProfile.ets
│ │ ├── Index.ets
│ │ ├── build-profile.json5
│ │ ├── consumer-rules.txt
│ │ ├── hvigorfile.ts
│ │ ├── obfuscation-rules.txt
│ │ ├── oh-package-lock.json5
│ │ ├── oh-package.json5
│ │ └── src
│ ├── library.har
│ ├── oh-package-lock.json5
│ └── oh-package.json5
├── index.ts
├── package.json
└── src
└── specs
├── arkts-components
├── cpp-components
└── turbo-modules
14 directories, 23 files
rn-lib-math/harmony/build-profile.json5 配置修改
"useNormalizedOHMUrl": false
这里不修改library编译出的har包里面没有其他资源文件,包括cpp目录
rn-lib-math/harmony/oh-package.json5 里面配置react-native-harmony.har 这个在npm i后会安装到本地
"dependencies": {
"@rnoh/react-native-openharmony": "file:../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har"
},
"overrides": {
"@rnoh/react-native-openharmony": "file:../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har"
}
rn-lib-math/harmony/library/oh-package.json5 里配置name 和 react_native_openharmony.har依赖
{
"name": "@rnoh/rn-lib-math",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@rnoh/react-native-openharmony": "file:../../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har"
}
}
harmony/entry/build-profile.json5 添加react-native-openharmony.har依赖,这个entry工程不过是为了调试
"dependencies": {
"@rnoh/react-native-openharmony": "file:../../node_modules/@react-native-oh/react-native-harmony/react_native_openharmony.har",
"@rnoh/rn-lib-math": "file:../library"
}
harmony/entry/build-profile.json5 添加externalNativeOptions配置
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
},
"resOptions": {
"copyCodeResource": {
"enable": false
}
}
},
harmony/entry/src/main/cpp/CMakeLists.txt
project(rnapp)
cmake_minimum_required(VERSION 3.5)
set(OH_MODULES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/@rnoh/react-native-openharmony/src/main/cpp")
set(WITH_HITRACE_SYSTRACE 1)
add_compile_definitions(WITH_HITRACE_SYSTRACE)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
add_subdirectory("${OH_MODULES_DIR}/@rnoh/rn-lib-math/src/main/cpp" ./rn-lib-math)
file(GLOB_RECURSE GENERATED_CPP_FILES "./generated/*.cpp")
file(GLOB package_src CONFIGURE_DEPENDS *.cpp)
add_library(rnoh_app SHARED
${GENERATED_CPP_FILES}
${VISION_CAMERA_CPP_FILES}
${package_src}
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
target_link_libraries(rnoh_app PUBLIC rn-lib-math)
在package.json目录下运行。==npm run codeine-lib ==
生成cpp 和 arkts代码
三、 将生成的代码通过api 提供
harmony/library/src/main/cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
set(rn_lib_math_generated_dir "${CMAKE_CURRENT_SOURCE_DIR}/generated")
file(GLOB_RECURSE rn_lib_math_generated_SRC "${rn_lib_math_generated_dir}/**/*.cpp")
file(GLOB rn_lib_math_SRC CONFIGURE_DEPENDS *.cpp)
add_library(rn_lib_math SHARED ${rn_lib_math_generated_SRC} ${rn_lib_math_SRC} RnLibMathPackage.h RnLibMathPackage.cpp)
target_include_directories(rn_lib_math PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${rn_lib_math_generated_dir})
target_link_libraries(rn_lib_math PUBLIC rnoh)
harmony/library/src/main/cpp/RnLibMathPackage.h
#ifndef HARMONY_MATHPACKAGE_H
#define HARMONY_MATHPACKAGE_H
#include "generated/RNOH/generated/BaseRnLibMathPackage.h"
namespace rnoh {
class RnLibMathPackage:public BaseRnLibMathPackage {
using Super = BaseRnLibMathPackage;
public:
explicit RnLibMathPackage(Package::Context ctx):BaseRnLibMathPackage(ctx){}
ComponentInstance::Shared createComponentInstance(const ComponentInstance::Context& ctx) override ;
};
}
#endif //HARMONY_MATHPACKAGE_H
harmony/library/src/main/cpp/RnLibMathPackage.cpp
#include "RnLibMathPackage.h"
#include "RNOH/RNInstanceCAPI.h"
using namespace facebook;
namespace rnoh {
ComponentInstance::Shared RnLibMathPackage::createComponentInstance(const ComponentInstance::Context &ctx) {
return nullptr;
}
} // namespace rnoh
harmony/library/src/main/ets/RnLibMathModule.ets
import { EtsUITurboModule } from "@rnoh/react-native-openharmony";
import { TM } from "./generated/ts";
export class RnLibMathModule extends EtsUITurboModule implements TM.MathModule.Spec{
add(a: number, b: number): Promise<number> {
return Promise.resolve(a+b)
}
subtract(a: number, b: number): Promise<number> {
return Promise.resolve(a-b)
}
multiply(a: number, b: number): Promise<number> {
return Promise.resolve(a*b)
}
divide(a: number, b: number): Promise<number> {
return Promise.resolve(a/b)
}
}
harmony/library/src/main/ets/RnLibMathPackage.ets
import { RNOHPackage, UITurboModule, UITurboModuleContext } from "@rnoh/react-native-openharmony";
import { TM } from "./generated/ts";
import { RnLibMathModule } from "./RnLibMathModule";
export class RnLibMathPackage extends RNOHPackage {
getUITurboModuleFactoryByNameMap(): Map<string, (ctx: UITurboModuleContext) => UITurboModule | null> {
return new Map([
[TM.MathModule.NAME, (ctx) => new RnLibMathModule(ctx)]
])
}
}
编译harmony/library模块
生成har包位置在harmony/library/build/default/outputs/default/library.har
将har包拷贝到harmony 目录下
在package.json目录下运行 ==npm pack ==
将在根目录下生成 rn-lib-math-1.0.0.tgz文件
四、RNOH项目运行三方库
Package.json添加依赖,或者通过npm 命令指定路径安装这个tgz文件
"dependencies": {
"@react-native-oh/react-native-harmony": "^0.77.18-1",
"react": "18.3.1",
"react-native": "0.77.1",
"third-party-library": "file:../third-party-library/third-party-library-1.0.0.tgz",
"rn-lib-math": "file:../rn-lib-math/rn-lib-math-1.0.0.tgz"
},
npm i —verbose
安装完成后通过deveco studio 打开RNOH的harmony工程
harmony/hvigor/hvigor-config.json5添加插件依赖,只用添加一次,后面再集成其他rn三方库不用再配置
"dependencies": {
"@rnoh/hvigor-plugin": "file:../../node_modules/@react-native-oh/react-native-harmony-cli/harmony/rnoh-hvigor-plugin-0.77.22.tgz"
},
harmony/entry/hvigorfile.ts 文件改动
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
//
// export default {
// system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
// plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
// }
import { createRNOHModulePlugin } from "@rnoh/hvigor-plugin"
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins: [
createRNOHModulePlugin({
nodeModulesPath: "../node_modules",
codegen: null,
autolinking: {}
}),
]
}
同步工程后会生成这几个文件
harmony/entry/src/main/ets/RNOHPackagesFactory.ets
harmony/entry/src/main/cpp/RNOHPackagesFactory.h
harmony/entry/src/main/cpp/autolinking.cmake
CMakeLists.txt添加
include("${CMAKE_CURRENT_SOURCE_DIR}/autolinking.cmake")
autolink_libraries(rnoh_app) # 这个放最后一行,这个函数就是在autolinking.cmake中定义的
原来PackageProvider.cpp 改动
harmony/entry/src/main/cpp/PackageProvider.cpp
#include "RNOH/PackageProvider.h"
//#include "RNOH/generated/BaseTurbomoduleDemoPackage.h"
#include "generated/RNOHGeneratedPackage.h"
#include "RNOHPackagesFactory.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
auto packages = createRNOHPackages(ctx); //这里把生成的三方库创建的packages添加进来,与当前工程定义的package合并
packages.push_back(std::make_shared<RNOHGeneratedPackage>(ctx));//当前工程自己定义的Package
// packages.push_back(std::make_shared<BaseTurbomoduleDemoPackage>(ctx));
return packages;
}
harmony/entry/src/main/ets/RNPackagesFactory.ets
import {
RNOHPackage, RNPackageContext, UITurboModule, UITurboModuleContext
} from "@rnoh/react-native-openharmony";
import { TM } from "@rnoh/react-native-openharmony/generated/index"
import { createRNOHPackages } from "./RNOHPackagesFactory";
import { CalcModule } from "./turbomodule/CalcModule";
class GeneratedPackage extends RNOHPackage {
override getUITurboModuleFactoryByNameMap(): Map<string, (ctx: UITurboModuleContext) => UITurboModule | null> {
return new Map([
[TM.NativeCalc.NAME, (ctx) => new CalcModule(ctx)]
])
}
override async createEagerUITurboModuleByNameMap(ctx: UITurboModuleContext): Promise<Map<string, UITurboModule>> {
return new Map([
[TM.NativeCalc.NAME, new CalcModule(ctx)]
])
}
}
export function createRNPackages(ctx: RNPackageContext): RNOHPackage[] {
return [
...createRNOHPackages(ctx), //将三方库生成的packages添加进来
new GeneratedPackage(ctx)//其他自定义package
]
}
后续再依赖其他三方库不需要改动,这三个文件中的内容会自动刷新依赖项
harmony/entry/src/main/ets/RNOHPackagesFactory.ets
harmony/entry/src/main/cpp/RNOHPackagesFactory.h
harmony/entry/src/main/cpp/autolinking.cmake
在App.tsx ui程序中可以使用
import {MathModule} from 'rn-lib-math';
let a = await MathModule?.divide(100, 200);
运行rn程序调试
npm run start
npm run ohos
这里运行的ohos是为了方便运行鸿蒙工程,不需要在deveco studio下去运行app
Ohos script为:
"scripts": {
"ohos": "bash ohos.sh",
"start": "hdc rport tcp:8081 tcp:8081 && react-native start",
"codegen": "react-native codegen-harmony --cpp-output-path ./harmony/entry/src/main/cpp/generated --rnoh-module-path ./harmony/entry/oh_modules/@rnoh/react-native-openharmony",
"dev": "npm run codegen && react-native bundle-harmony --dev",
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"test": "jest"
},
ohos.sh内容,windows下可以翻译成bat脚本使用
#!/bin/bash
cd ./harmony && hvigorw --mode module -p module=entry@default -p product=default -p requiredDeviceType=phone assembleHap --analyze=normal --parallel --incremental --daemon
(/Applications/DevEco-Studio.app/Contents/tools/emulator/Emulator -hvd Huawei_Phone -path /Users/fangzhen/.Huawei/Emulator/deployed -imageRoot /Users/fangzhen/Library/Huawei/Sdk &)
echo "Waiting for the simulator to start..."
MAX_WAIT=60
WAITED=0
while [ $WAITED -lt $MAX_WAIT ]; do
if hdc list targets 2>/dev/null | grep -E "^127\.0\.0\.1:[0-9]+" | head -1; then
echo "simulator is ready"
break
fi
sleep 2
WAITED=$((WAITED + 2))
echo "Waiting for the simulator to start... ${WAITED} s"
done
if [ $WAITED -ge $MAX_WAIT ]; then
echo "Error: Simulator launch timeout"
exit 1
fi
hdc shell "aa force-stop com.rnoh.harmony"
hdc install "./entry/build/default/outputs/default/entry-default-unsigned.hap"
hdc shell "aa start -a EntryAbility -b com.rnoh.harmony"
exit
更多推荐


所有评论(0)