欢迎光临
我们一直在努力

React Native鸿蒙跨平台实战:从项目初始化到开源交付完整指南

React Native鸿蒙跨平台实战:从项目初始化到开源交付完整指南

在这里插入图片描述

前言:本文聚焦React Native for OpenHarmony项目的完整落地流程,涵盖从零开始搭建工程、多设备适配验证、到开源仓库标准化交付的全过程。每个环节都附带实际踩坑经验与解决方案,帮助开发者快速掌握鸿蒙跨平台开发实战技能。

一、项目初始化:工程结构规划与基础配置

1.1 工程目录设计

在开始编码前,合理的目录结构能大幅提升后续维护效率。以下是推荐的工程结构:

rnoh-multidevice-demo/
├── rn/ # React Native工程目录
│ ├── src/ # 源码目录
│ ├── package.json # RN依赖配置
│ └── metro.config.js # Metro打包配置
├── harmony/ # 鸿蒙工程目录
│ ├── entry/
│ │ ├── src/main/
│ │ │ ├── cpp/ # C++原生代码
│ │ │ ├── ets/ # ArkTS代码
│ │ │ └── resources/ # 资源文件
│ │ └── build-profile.json5 # 编译配置
│ └── oh-package.json5 # 鸿蒙依赖配置
├── docs/ # 文档目录
│ ├── screenshots/ # 运行截图
│ └── logs/ # 日志文件
├── .gitignore # Git忽略配置
└── README.md # 项目说明

1.2 创建React Native工程

# 使用0.72.5版本(当前RNOH稳定支持版本)
npx react-native@0.72.5 init RnohMultideviceDemo –version 0.72.5

# 进入项目目录
cd RnohMultideviceDemo

# 安装鸿蒙适配包
npm install @react-native-oh/react-native-harmony@0.72.90

1.3 配置Metro打包工具

修改metro.config.js文件,添加鸿蒙平台支持:

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require("@react-native-oh/react-native-harmony/metro.config");

const config = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
resolver: {
// 添加鸿蒙平台扩展解析
sourceExts: ['jsx', 'js', 'ts', 'tsx', 'harmony.ts'],
}
};

module.exports = mergeConfig(
getDefaultConfig(__dirname),
createHarmonyMetroConfig({
reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
}),
config
);

1.4 创建鸿蒙工程

  • 打开DevEco Studio,选择「Empty Ability」模板

  • 工程存储位置设置为RN项目根目录下的harmony文件夹

  • 配置项目信息:

    • 包名:com.example.rnoh.multidevice
    • 最低API版本:API 20
    • 设备类型:Phone
  • 在entry目录下安装鸿蒙依赖:

  • cd harmony/entry
    ohpm install @rnoh/react-native-openharmony@0.72.90

    二、SDK环境配置:全量安装与工具链集成

    2.1 全量SDK安装

    问题:默认安装的Public SDK缺少系统级API,导致编译时报错"找不到类/方法"。

    解决方案:

  • 打开DevEco Studio,进入「File → Settings → OpenHarmony SDK」
  • 勾选API Version 20,选择「Full SDK」
  • 同时安装「Toolchains」和「Emulator」组件
  • 2.2 环境变量配置

    配置系统环境变量,确保工具链全局可用:

    变量名变量值说明
    OH_SDK_HOME D:\\Huawei\\Sdk\\default\\openharmony SDK根目录
    HDC_SERVER_PORT 7035 HDC服务端口
    RNOH_C_API_ARCH 1 启用CAPI架构
    PATH追加 %OH_SDK_HOME%\\toolchains HDC命令路径

    PowerShell配置示例:

    # 设置SDK根目录
    [Environment]::SetEnvironmentVariable("OH_SDK_HOME", "D:\\Huawei\\Sdk\\default\\openharmony", "User")

    # 设置HDC端口
    [Environment]::SetEnvironmentVariable("HDC_SERVER_PORT", "7035", "User")

    # 启用CAPI架构
    [Environment]::SetEnvironmentVariable("RNOH_C_API_ARCH", "1", "User")

    # 追加PATH(需要手动编辑系统环境变量)

    2.3 验证配置

    # 验证HDC工具
    hdc version
    # 预期输出:hdc version 1.4.2

    # 验证CAPI变量
    echo %RNOH_C_API_ARCH%
    # 预期输出:1

    三、多终端适配配置

    3.1 编译架构配置

    修改harmony/entry/build-profile.json5,支持多种CPU架构:

    {
    "apiType": "stageMode",
    "buildOption": {
    "externalNativeOptions": {
    "path": "./src/main/cpp/CMakeLists.txt",
    "arguments": "",
    "cppFlags": "-fPIC -std=c++17",
    "abiFilters": [
    "arm64-v8a", // 真机/开发板
    "x86_64" // 模拟器
    ]
    }
    },
    "targets": [
    {
    "name": "default",
    "runtimeOS": "HarmonyOS"
    }
    ]
    }

    3.2 设备类型与权限配置

    修改harmony/entry/src/main/module.json5:

    {
    "module": {
    "name": "entry",
    "type": "entry",
    "deviceTypes": [
    "phone", // 手机
    "tablet", // 平板
    "2in1" // 二合一设备
    ],
    "requestPermissions": [
    {
    "name": "ohos.permission.INTERNET",
    "reason": "$string:internet_reason",
    "usedScene": {
    "abilities": ["EntryAbility"],
    "when": "inuse"
    }
    },
    {
    "name": "ohos.permission.GET_NETWORK_INFO"
    }
    ]
    }
    }

    3.3 CMakeLists.txt配置

    在harmony/entry/src/main/cpp/CMakeLists.txt中配置编译选项:

    cmake_minimum_required(VERSION 3.4.1)
    project(RnohMultideviceDemo)

    set(CMAKE_SKIP_BUILD_RPATH TRUE)
    set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
    set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")

    set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument")
    set(CMAKE_CXX_FLAGS "-fstack-protector-strong -fPIE -pie")
    add_compile_definitions(WITH_HITRACE_SYSTRACE)

    add_subdirectory("${RNOH_CPP_DIR}" ./rn)

    add_library(rnoh_app SHARED
    "${CMAKE_CURRENT_SOURCE_DIR}/PackageProvider.cpp"
    "${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
    )

    target_link_libraries(rnoh_app PUBLIC rnoh)

    # 添加架构特定配置
    if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
    target_compile_definitions(rnoh_app PRIVATE ARCH_X86_64)
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
    target_compile_definitions(rnoh_app PRIVATE ARCH_ARM64)
    endif()

    3.4 PackageProvider.cpp实现

    #include "RNOH/PackageProvider.h"
    #include <vector>

    using namespace rnoh;

    std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    // 返回空数组,后续可添加自定义Package
    return {};
    }

    3.5 ArkTS层配置

    3.5.1 EntryAbility.ets

    import { RNAbility } from '@rnoh/react-native-openharmony';

    export default class EntryAbility extends RNAbility {
    protected getPagePath(): string {
    return "pages/IndexPage"
    }

    override onCreate(want: Want): void {
    super.onCreate(want);
    }

    override onDestroy(): void {
    super.onDestroy();
    }
    }

    3.5.2 创建RNPackagesFactory.ets

    在harmony/entry/src/main/ets/目录下创建:

    import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';

    export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
    return [];
    }

    3.5.3 IndexPage.ets(主页面)

    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 IndexPage {
    @StorageLink('RNOHCoreContext') private rnohContext: RNOHCoreContext | undefined = undefined
    @State shouldShow: boolean = false
    private logger!: RNOHLogger

    aboutToAppear() {
    this.logger = this.rnohContext!.logger.clone("IndexPage")
    this.shouldShow = true
    }

    onBackPress(): boolean {
    this.rnohContext!.dispatchBackPress()
    return true
    }

    build() {
    Column() {
    if (this.rnohContext && this.shouldShow) {
    if (this.rnohContext?.isDebugModeEnabled) {
    RNOHErrorDialog({ ctx: this.rnohContext })
    }
    RNApp({
    rnInstanceConfig: {
    createRNPackages,
    enableNDKTextMeasuring: true,
    enableBackgroundExecutor: false,
    enableCAPIArchitecture: true,
    arkTsComponentNames: []
    },
    initialProps: {},
    appKey: "RnohMultideviceDemo",
    wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
    onSetUp: (rnInstance) => {
    rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
    },
    jsBundleProvider: new TraceJSBundleProviderDecorator(
    new AnyJSBundleProvider([
    new MetroJSBundleProvider(),
    new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
    new ResourceJSBundleProvider(this.rnohContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
    ]),
    this.rnohContext.logger),
    })
    }
    }
    .width('100%')
    .height('100%')
    }
    }

    3.6 React Native响应式布局适配

    在RN项目中创建适配不同屏幕尺寸的组件:

    // rn/src/components/ResponsiveLayout.tsx
    import React from 'react';
    import {
    View,
    Text,
    StyleSheet,
    Dimensions,
    Platform
    } from 'react-native';

    const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

    // 设备类型判断
    const getDeviceType = () => {
    if (Platform.isPad) return 'tablet';
    if (screenWidth < 600) return 'phone';
    return 'tablet';
    };

    export const ResponsiveLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const deviceType = getDeviceType();
    const styles = createStyles(deviceType);

    return (
    <View style={styles.container}>
    <Text style={styles.title}>
    {deviceType === 'phone' ? '手机端' : '平板端'}布局
    </Text>
    {children}
    </View>
    );
    };

    const createStyles = (deviceType: string) => StyleSheet.create({
    container: {
    flex: 1,
    padding: deviceType === 'phone' ? 16 : 32,
    backgroundColor: deviceType === 'phone' ? '#f5f5f5' : '#e8f4f8',
    },
    title: {
    fontSize: deviceType === 'phone' ? 20 : 28,
    fontWeight: 'bold',
    marginBottom: 16,
    },
    });

    // 监听屏幕尺寸变化
    export class ResponsiveScreen extends React.Component {
    state = {
    dimensions: Dimensions.get('window'),
    };

    componentDidMount() {
    Dimensions.addEventListener('change', this.handleDimensionChange);
    }

    componentWillUnmount() {
    Dimensions.removeEventListener('change', this.handleDimensionChange);
    }

    handleDimensionChange = ({ window }) => {
    this.setState({ dimensions: window });
    };

    render() {
    return (
    <ResponsiveLayout>
    <Text>屏幕宽度: {this.state.dimensions.width}</Text>
    <Text>屏幕高度: {this.state.dimensions.height}</Text>
    </ResponsiveLayout>
    );
    }
    }

    四、多设备运行验证

    4.1 真机调试配置

    4.1.1 设备准备

  • 手机开启开发者模式:设置 → 关于手机 → 连续点击版本号7次
  • 启用USB调试和USB安装
  • 连接电脑,确认设备被识别
  • 4.1.2 驱动安装

    # 查看连接设备
    hdc list targets

    # 查看设备信息
    hdc device info

    # 安装应用(需先生成hap包)
    hdc install entry-signed.hap

    4.1.3 签名配置

    在DevEco Studio中配置自动签名:

    // harmony/entry/build-profile.json5
    {
    "app": {
    "signingProfiles": [
    {
    "name": "default",
    "type": "HarmonyOS",
    "material": {
    "certpath": "自动生成",
    "storePassword": "自动生成",
    "keyAlias": "自动生成",
    "keyPassword": "自动生成"
    }
    }
    ]
    }
    }

    4.2 模拟器调试

    4.2.1 创建模拟器

  • 打开Device Manager → Emulator Manager
  • 创建Phone模拟器,选择API 20
  • 内存分配至少4GB
  • 4.2.2 启动模拟器

    # 检查模拟器状态
    hdc list targets

    # 端口转发(用于Metro热更新)
    hdc rport tcp:8081 tcp:8081

    4.3 证据留存规范

    创建文档目录结构存放运行证据:

    docs/
    ├── screenshots/
    │ ├── phone_main_screen.png
    │ ├── tablet_layout.png
    │ └── emulator_running.png
    └── logs/
    ├── phone_build_log.txt
    ├── tablet_runtime_log.txt
    └── emulator_debug_log.txt

    导出日志脚本(PowerShell):

    # export_logs.ps1
    $timestamp = Get-Date Format "yyyyMMdd_HHmmss"
    $logDir = "docs/logs"
    New-Item ItemType Directory Force Path $logDir

    # 导出编译日志
    hdc shell hilog > "$logDir/build_$timestamp.txt"

    # 导出运行时日志
    hdc shell hilog x > "$logDir/runtime_$timestamp.txt"

    五、开源仓库标准化配置

    5.1 仓库创建规范

    在AtomGit/Gitee/GitHub创建仓库时遵循以下规范:

    配置项推荐值说明
    仓库名称 rnoh-multidevice-demo 小写+连字符
    描述 React Native鸿蒙跨平台Demo,支持多终端运行 清晰说明项目用途
    许可证 Apache-2.0 OpenHarmony官方推荐
    默认分支 main 现代Git规范

    5.2 .gitignore配置

    创建完整的忽略规则:

    # 编译产物
    build/
    .ohos/
    entry/build/
    *.hap
    *.app

    # IDE配置
    .idea/
    .vscode/
    *.iml
    .cxx/

    # 依赖包
    node_modules/
    oh_modules/

    # 日志文件
    *.log
    hilog/

    # 临时文件
    .DS_Store
    Thumbs.db
    *~
    *.swp
    *.swo

    # 测试覆盖率
    coverage/
    .nyc_output/

    # 打包文件
    *.tar.gz
    *.zip

    5.3 README.md模板

    # RNOH多设备适配示例

    React Native for OpenHarmony多终端适配示例项目,支持手机、平板、模拟器运行。

    ## 运行环境

    – Node.js: 16+
    – DevEco Studio: 6.0+
    – OpenHarmony SDK: API 20
    – React Native: 0.72.5

    ## 快速开始

    ### 安装依赖

    \\`\\`\\`bash
    # RN侧依赖
    cd rn
    npm install

    # 鸿蒙侧依赖
    cd ../harmony/entry
    ohpm install
    \\`\\`\\`

    ### 生成Bundle

    \\`\\`\\`bash
    cd rn
    npm run harmony
    \\`\\`\\`

    ### 运行项目

    1. 用DevEco Studio打开`harmony`目录
    2. 选择目标设备(真机/模拟器)
    3. 点击运行按钮

    ## 项目结构

    \\`\\`\\`
    rnoh-multidevice-demo/
    ├── rn/ # React Native工程
    ├── harmony/ # 鸿蒙工程
    └── docs/ # 文档与运行证据
    \\`\\`\\`

    ## 支持设备

    – 华为/荣耀手机(HarmonyOS 4.0+)
    – 平板设备
    – DevEco Studio模拟器

    ## 常见问题

    ### 签名错误
    在DevEco Studio中选择自动签名配置。

    ### bundle文件未生成
    确保`metro.config.js`配置正确,重新执行`npm run harmony`。

    ## 许可证

    Apache-2.0

    5.4 提交规范

    # 功能开发
    git commit -m "feat: 添加平板布局适配"

    # 问题修复
    git commit -m "fix: 解决模拟器白屏问题"

    # 文档更新
    git commit -m "docs: 更新README运行说明"

    # 配置修改
    git commit -m "build: 更新SDK版本到API 20"

    六、常见问题与解决方案

    6.1 编译问题

    问题1:找不到RNOH头文件

    # 检查CMakeLists.txt中的路径配置
    message("OH_MODULE_DIR: ${OH_MODULE_DIR}")
    message("RNOH_CPP_DIR: ${RNOH_CPP_DIR}")

    # 确保路径正确指向oh_modules目录

    问题2:架构不兼容

    # 检查设备架构
    hdc shell uname -m

    # 根据设备架构调整abiFilters配置
    # aarch64 → arm64-v8a
    # x86_64 → x86_64

    6.2 运行时问题

    问题3:应用白屏

    // 检查appKey是否匹配
    // rn/index.js
    AppRegistry.registerComponent('RnohMultideviceDemo', () => App);

    // harmony/IndexPage.ets
    appKey: "RnohMultideviceDemo" // 必须一致

    问题4:热更新不生效

    # 配置端口转发
    hdc rport tcp:8081 tcp:8081

    # 启动Metro服务
    npm start

    # 在Metro界面按r键重新加载

    6.3 真机调试问题

    问题5:设备连接失败

    # 重启HDC服务
    hdc kill
    hdc start

    # 检查USB调试是否开启
    hdc list targets

    问题6:安装失败

    # 卸载旧版本
    hdc uninstall com.example.rnoh.multidevice

    # 清理缓存
    hdc shell rm -rf /data/storage/el2/base/files/*

    七、总结

    通过本指南,我们完成了:

  • ✅ React Native鸿蒙工程的初始化与配置
  • ✅ 多终端(手机/平板/模拟器)的适配配置
  • ✅ 响应式布局的实现
  • ✅ 开源仓库的标准化配置
  • ✅ 常见问题的解决方案
  • 关键要点回顾:

    • 使用Full SDK确保API完整性
    • 配置多架构支持实现跨设备运行
    • 规范的Git提交和文档提升项目可维护性
    • 完整的证据留存便于技术分享

    下一步学习建议:

    • 深入学习TurboModule自定义原生模块
    • 掌握Fabric组件开发
    • 探索RNOH性能优化技巧

    参考资源:

    • React Native官方文档
    • OpenHarmony开发者文档
    • RNOH GitHub仓库

    欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

    赞(0)
    未经允许不得转载:171主机测评 » React Native鸿蒙跨平台实战:从项目初始化到开源交付完整指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址