0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Taro鸿蒙技术内幕系列(一):如何将React代码跑在ArkUI上

京东云 来源:jf_75140285 2024-10-25 17:24 次阅读

作者:京东零售 朱鸣辉

基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章将深入解析 Taro 如何实现使用 React 开发高性能鸿蒙应用的技术内幕

背景

随着鸿蒙操作系统的快速发展,开发者们期待将现有跨平台应用迁移到鸿蒙平台。Taro作为一个流行的跨平台开发框架,其支持鸿蒙系统的可能性引起了广泛关注。

然而,鸿蒙系统采用全新的ArkUI框架作为原生UI开发方案,与Taro原本支持的平台存在显著差异。将Taro的React开发模式与ArkUI的声明式UI开发范式进行有效对接成为了一个技术难题。

本文将探讨Taro框架如何通过创新方案实现React代码在ArkUI上的运行。我们将解析Taro的运行时原理,剖析其如何将React组件转换为ArkUI可识别的结构,以及相关技术挑战和解决方案。

Taro运行时原理介绍

为了理解Taro适配ArkUI的核心机制,我们首先需要深入了解Taro的运行时原理。Taro通过巧妙的设计,将React代码转换为各平台可执行的形式,其中包括对鸿蒙平台的适配。下面将详细介绍 Taro 是如何将 React 代码转换为ArkUI可执行的形式,以及节点转换的流程细节。

wKgaoWcXQA-AX6UzABGMbiseADc620.png

1. 从 React 到 Taro

React 跨平台的秘诀

在 Taro 的运行时中,首先执行的是开发者编写的 React 业务代码。这些代码定义了业务应用的结构、逻辑和状态管理。那么既然要对接React,那肯定先得了解它的核心架构,React是怎么运作的:

wKgZoWcXQBOAUyutABPiFdo-BPA686.png



了解了React的基本架构后,我们可以清晰地看到,Renderer 作为渲染器,负责将React的虚拟节点操作最终映射到相应的平台上。例如,react-dom将这些操作对接到浏览器上,而react-native则将其对接到iOSAndroid平台。这种设计使得React能够适配不同的运行环境。

wKgZoWcXQBaAXIhDABLU5H_VvK4697.png

正是基于这种思路,Taro 团队设计了 Taro Renderer。这个渲染器充当了 React 与 Taro 虚拟节点树之间的桥梁,使得 React 的操作可以被转换为 Taro 的中间表示。

通过实现 Taro Renderer 生成 Taro 虚拟节点树

wKgaoWcXQBeASkU4AAU2ooqu32s867.png

HostConfig接口实现



要实现 Taro 的 Renderer,我们需要实现 React Reconciler 所需的 hostConfig 接口。这个接口定义了一系列方法,用于创建、更新和管理渲染目标平台的元素。以下是一些关键的 hostConfig 方法:

createElement:创建ArkUI对应的元素。

createTextInstance:创建文本节点。

appendChild:将子元素添加到父元素。

removeChild:从父元素中移除子元素。

insertBefore:在指定位置插入元素。

commitUpdate:更新元素属性。

通过实现这些方法,Taro Renderer 能够将 React 的操作转换为 Taro 虚拟节点树的相应操作。这个虚拟节点树是 Taro 实现跨平台的核心,它为不同平台的渲染提供了统一的中间表示。

// 部分HostConfig接口实现的代码

const hostConfig: HostConfig {
    // 创建Taro虚拟节点
  createInstance (type, props: Props, _rootContainerInstance, _hostContext, internalInstanceHandle: Fiber) {
    const element: TaroElement = TaroNativeModule.createTaroNode(type)
    precacheFiberNode(internalInstanceHandle, element)
    updateFiberProps(element, props)
    return element
  },
  // 更新属性
    commitUpdate (dom, updatePayload, _, oldProps, newProps) {
      updatePropsByPayload(dom, oldProps, updatePayload)
      updateFiberProps(dom, newProps)
    },
    // 插入节点
    insertBefore (parent: TaroElement, child: TaroElement, refChild: TaroElement) {
      parent.insertBefore(child, refChild)
    },
    // 移除节点
    removeChild (parent: TaroElement, child TaroElement) {
      parent.removeChild(child)
    },
    // ...
}

2. 从 Taro 到 ArkUI

在将 Taro 虚拟节点树转换为 ArkUI 的过程中,我们需要进行几个关键步骤:



wKgZoWcXQBuAXDLKAAiIYMZZYbo181.png

Taro Element转换 ArkUI过程

首先,我们需要在 ArkUI 层面实现一套与 Taro 组件对应的组件库。这个步骤至关重要,因为它建立了 Taro 组件和 ArkUI 组件之间的映射关系。例如,我们需要为 Taro 的 View、Text、Image 等基础组件创建对应的 ArkUI 组件。这样,当我们遍历 Taro 虚拟节点树时,就能找到每个节点在 ArkUI 中的对应实现。



在节点映射的过程中,我们注意到 Taro 虚拟节点树与实际 ArkUI 视图结构存在差异。这些差异主要体现在以下几个方面:

复合组件结构:某些 Taro 组件在 ArkUI 中可能需要多个组件配合实现。例如,ScrollView 组件在 ArkUI 中可能需要一个 Scroll 节点搭配一个 Stack 来实现完整功能。

层级位置调整:一些特殊定位的节点(如 Fixed 定位的元素)在最终渲染时的位置可能与其在虚拟节点树中的层级不一致。这需要在生成渲染树时进行特殊处理。

平台特定组件:某些 Taro 组件可能需要使用 ArkUI 特有的组件或布局方式来实现,这要求我们在转换过程中进行适当的调整和映射。

wKgaoWcXQB2AKlzcAAkvMJEcN_w449.png

因此,在生成渲染树时,我们需要一个更复杂的转换过程,不仅要考虑简单的一对一映射,还要处理这些结构性的差异,确保最终生成的 ArkUI 组件树能够正确反映预期的视图结构和布局。因此,在Taro > ArkUI的节点对接中,我们需要维护一棵 Render Tree,用于做中间的桥梁。



1. 根据组件类型 创建 Taro Element

在创建 Taro Element 的过程中,我们根据组件的类型来实例化相应的 Taro 元素。这一步骤是将 React 组件转换为 Taro 内部表示的关键。

// 根据组件类型创建对应的Taro节点
std::shared_ptr< TaroElement > TaroDocument::CreateElement(napi_value &node) {
        // 获取组件类型
    TAG_NAME tag_name_ = TaroDOM::TaroElement::GetTagName(node);
    // 根据组件类型,创建对应的实例
    std::shared_ptr< TaroDOM::TaroElement > item;
    switch (tag_name_) {
        case TAG_NAME::SCROLL_VIEW: {
            item = std::make_shared< TaroDOM::TaroScrollView >(node);
            break;
        }
        case TAG_NAME::IMAGE:
            item = std::make_shared< TaroDOM::TaroImage >(node);
            break;
        }
        case TAG_NAME::SPAN:
        case TAG_NAME::TEXT: {
            item = std::make_shared< TaroDOM::TaroText >(node);
            break;
        }
        case TAG_NAME::SWIPER: {
            item = std::make_shared< TaroDOM::TaroSwiper >(node);
            break;
        }
        // ...
    }
    return item;
}

2. Taro Element 创建 Taro RenderNode

在创建完 Taro Element 之后,下一步是将其转换为 Taro RenderNode。这个过程是将 Taro 的内部表示进一步转化为更接近 ArkUI 结构的渲染节点。

// 创建 Taro RenderNode
void TaroSwiper::Build() {
    if (!is_init_) {
        // create render node
        TaroElementRef element = std::static_pointer_cast< TaroElement >(shared_from_this());
        auto render_swiper = std::make_shared< TaroSwiperNode >(element);
        render_swiper->Build();
    }
}

3. Taro RenderNode 创建 ArkUI Node

最后一步是将 Taro RenderNode 转换为实际的 ArkUI 节点。这个过程涉及到直接与 ArkUI 的底层 API 交互,创建和配置 ArkUI 的原生节点。实现了从 Taro 的渲染节点到 ArkUI 实际可渲染节点的最终转换。

 // 创建 ArkUI Node
void TaroSwiperNode::Build() {
    NativeNodeApi *nativeNodeApi = NativeNodeApi::getInstance();
    // 创建一个Swiper的ArkUI节点
    SetArkUINodeHandle(nativeNodeApi->createNode(ARKUI_NODE_SWIPER));
}

通过这三个步骤,我们在 C++ 层面成功实现了 React 组件结构到 ArkUI 原生组件结构的映射。这一过程使 Taro 应用能够在鸿蒙系统上准确地渲染和运行,为跨平台开发提供了有力支持。

总结

最后总结下,本文探讨了Taro框架如何将React代码成功运行在鸿蒙系统的ArkUI上。这个过程主要分为两个关键部分:

wKgaoWcXQB-AfkaKAAmbVAbNNpQ388.png

React > ArkUI 架构图

1. Taro对接React

Taro通过实现自定义的Renderer来对接React。这个Renderer包含了一系列方法,如createInstance、commitUpdate等,用于将React的操作转换为Taro虚拟节点树的操作。这个虚拟节点树是Taro实现跨平台的核心,为不同平台的渲染提供了统一的中间表示。

2. Taro对接ArkUI

Taro通过自定义Renderer将React操作转换为虚拟节点树,然后通过三步转换过程将其映射到ArkUI结构。这个过程涉及Taro Element、Taro RenderNode和ArkUI Node这三棵树的维护,主要通过这三个流程步骤实现:

1.创建Taro Element:这一步将React组件转换为Taro内部表示。

2.创建Taro RenderNode:将Taro的内部表示进一步转化为更接近ArkUI层级结构的渲染节点。

3.创建ArkUI Node:最后一步是将Taro RenderNode转换为实际的ArkUI节点,直接与ArkUI的底层API交互。

通过这种方式,Taro成功地将React组件结构映射到ArkUI原生组件结构,使得Taro应用能够在鸿蒙系统上准确地渲染和运行,同时也为跨平台开发提供了有力支持。


系列往期精选:

《京东鸿蒙上线前瞻——使用 Taro 打造高性能原生应用》

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    6818

    浏览量

    123320
  • APP
    APP
    +关注

    关注

    33

    文章

    1573

    浏览量

    72473
  • 代码
    +关注

    关注

    30

    文章

    4786

    浏览量

    68568
收藏 人收藏

    评论

    相关推荐

    鸿蒙开发学习:初探【ArkUI-X】

    **简单来说,ArkTS + ArkUI-X 对标的框架为 flutter,代码,编译为 native 全平台运行**
    的头像 发表于 05-13 15:58 1032次阅读
    <b class='flag-5'>鸿蒙</b>开发学习:初探【<b class='flag-5'>ArkUI</b>-X】

    鸿蒙开发ArkUI-X基础知识:【ArkUI代码工程及构建介绍】

    ArkUI作为OpenHarmony的默认开发框架,本项目(ArkUI-X)中需要做到代码同时支持多平台构建,所以会采取共仓开发的方式
    的头像 发表于 05-25 16:45 2085次阅读
    <b class='flag-5'>鸿蒙</b>开发<b class='flag-5'>ArkUI</b>-X基础知识:【<b class='flag-5'>ArkUI</b><b class='flag-5'>代码</b>工程及构建介绍】

    鸿蒙Flutter实战:07混合开发

    # 鸿蒙Flutter实战:混合开发 鸿蒙Flutter混合开发主要有两种形式。 ## 1.基于har flutter module打包成har包,原生
    发表于 10-23 16:00

    鸿蒙Taro实战:01-搭建开发环境

    ,点击右下角 Apply, OK, 完成签名 运行 DevEcho 中,点击运行按钮,待控制台执行完成,查看设备,页面中将输出以下内容 首页 Hello world! 注意事项 运动 Taro
    发表于 11-06 16:42

    Taro下拉加载更多,拉刷新是什么

    Taro下拉加载更多,拉刷新
    发表于 06-15 17:10

    如何将RF与数模电路设计PCB

    如何将RF与数模电路设计PCB
    发表于 01-12 21:59 17次下载

    如何将手机系统升级为鸿蒙系统

    如何将手机系统升级为鸿蒙系统?具体操作还是很简单的,下面就跟小编起来学学看吧!
    的头像 发表于 07-07 10:03 5681次阅读

    如何在鸿蒙系统ArkUI应用

          大家可以看到很明显这是ArkUI 的应用,远程模拟器目前还只可以 P4
    的头像 发表于 11-15 09:28 2990次阅读
    如何在<b class='flag-5'>鸿蒙</b>系统<b class='flag-5'>上</b>弄<b class='flag-5'>一</b>个<b class='flag-5'>ArkUI</b>应用

    鸿蒙ArkUI开发-Tabs组件的使用

    鸿蒙ArkUI开发-Tabs组件的使用
    的头像 发表于 01-19 16:01 1886次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b>开发-Tabs组件的使用

    使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

    鸿蒙原生应用。 《使用 Taro 开发鸿蒙原生应用》 系列文章中,我们已经介绍了 鸿蒙的基
    的头像 发表于 02-02 16:09 874次阅读
    使用 <b class='flag-5'>Taro</b> 开发<b class='flag-5'>鸿蒙</b>原生应用 —— 快速上手,<b class='flag-5'>鸿蒙</b>应用开发指南

    鸿蒙ArkUI:【从代码到UI显示的整体渲染流程】

    方舟开发框架(简称ArkUI)是鸿蒙开发的UI框架,提供如下两种开发范式,我们 **只学声明式开发范式**
    的头像 发表于 05-13 16:06 913次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b>:【从<b class='flag-5'>代码</b>到UI显示的整体渲染流程】

    鸿蒙跨平台框架:【ArkUi-X】创建工程

    鸿蒙推出了鸿ArkUi-X 框架所以就写个文章分享
    的头像 发表于 05-13 17:48 948次阅读
    <b class='flag-5'>鸿蒙</b>跨平台框架:【<b class='flag-5'>ArkUi</b>-X】创建工程

    鸿蒙ArkUI-X跨平台开发:【 编写第ArkUI-X应用】

    通过构建个简单的ArkUI页面跳转示例,快速了解资源创建引用,路由代码编写和UI布局编写等应用开发流程。
    的头像 发表于 05-21 17:36 694次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>ArkUI</b>-X跨平台开发:【 编写第<b class='flag-5'>一</b>个<b class='flag-5'>ArkUI</b>-X应用】

    Taro 鸿蒙技术内幕系列(二):如何让 W3C 标准的 CSS鸿蒙

    作者:京东零售 马银涛   基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章深入解析
    的头像 发表于 10-31 10:54 163次阅读
    <b class='flag-5'>Taro</b> <b class='flag-5'>鸿蒙</b><b class='flag-5'>技术</b><b class='flag-5'>内幕</b><b class='flag-5'>系列</b>(二):如何让 W3C 标准的 CSS<b class='flag-5'>跑</b><b class='flag-5'>在</b><b class='flag-5'>鸿蒙</b>上

    Taro 鸿蒙技术内幕系列(三) - 多语言场景下的通用事件系统设计

    作者:京东零售 朱天健 基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章深入解析
    的头像 发表于 11-27 11:42 197次阅读
    <b class='flag-5'>Taro</b> <b class='flag-5'>鸿蒙</b><b class='flag-5'>技术</b><b class='flag-5'>内幕</b><b class='flag-5'>系列</b>(三) - 多语言场景下的通用事件系统设计