写点什么

HDC 技术分论坛:HarmonyOS 新一代 UI 框架的全面解读

  • 2021 年 11 月 18 日
  • 本文字数:4258 字

    阅读完需:约 14 分钟

HDC技术分论坛:HarmonyOS新一代UI框架的全面解读

作者:yuzhiqiang,UI 编程框架首席技术专家

在 Harmony 3.0.0 开发者预览版中,包含了新一代的声明式 UI 框架 ArkUI 3.0、多语言跨平台编译器 ArkCompiler 3.0、跨端开发工具 DevEco Studio3.0,以及基于 TS/JS 语言的 API 7,全面提升开发者体验。

本期,我们要为大家重点介绍 HarmonyOS 新一代声明式 UI 框架 ArkUI 3.0。

一、UI 编程框架

在介绍 ArkUI 3.0 之前,我们先来简要了解一下什么是 UI 编程框架。

UI 编程框架,是为应用开发者提供的开发 UI 的基础设施,主要包括 UI 控件(按钮/列表等),视图布局(摆放/排列相应的 UI 控件),动画机制(动画设计以及效果呈现),交互事件处理(点击/滑动等),以及相应的编程语言和编程模型等。从系统运行的维度来看,UI 编程框架也包括一个运行时,负责应用在系统中执行时所需的资源加载、UI 渲染和事件响应等。

总体而言,UI 编程框架提供了开发以及运行 UI 界面所需要的框架能力,主要架构如下图所示:

图 1 UI 编程框架

  • 开发模型:对开发者提供开发范式、UI 控件/布局/动效/交互、编程语言等。它体现的是开发效率与难易程度。

  • 运行框架:UI 界面渲染及交互的基础能力框架,包括相应的布局引擎、控件机制、动效引擎、事件机制、渲染管线等,并结合语言虚拟机和图形引擎,将开发者的程序运行在具体系统平台上。它体现的是应用运行的性能体验。

  • 平台适配:承载框架的具体操作系统或平台适配层。

UI 编程框架的关键需求,主要有以下两类:

  1. 开发效率:包括代码量、学习曲线、工具、社区、三方库完备度等。

  2. 性能体验:包括启动速度、帧率、响应时延、酷炫效果、资源占用等。

另外,随着智能设备的急剧增长,UI 编程框架还需要考虑如何更好地适配不同设备的差异性,包括设备形态差异(比如屏幕形状、尺寸、分辨率、交互模式等),以及设备能力差异(比如内存、CPU、GPU 等)。

二、ArkUI 框架的演进

为了更好地满足开发效率和性能体验等相关的需求, ArkUI 3.0 综合考虑了 UI 渲染以及语言和运行时,围绕着极简开发、高性能、跨设备跨平台进一步演进。下图描述了 ArkUI 整体架构的演进:

图 2 ArkUI 框架演进

图的左侧是 2020 年发布的 JS UI 框架的架构示意图。它主要支持类 Web 的前端开发范式,通过 DSL(domain-specific language,领域特定语言)转换层,跨语言对接到声明式 UI 后端引擎,并结合 JS 引擎完成整体 UI 渲染。图的右侧是新的 ArkUI 3.0 框架,主要有以下几个关键的变化:

(1)引入了新一代的声明式 UI 开发范式,实现极简的 UI 描述语法。

(2)设计了统一的前后端扁平化渲染机制,进一步提升 UI 渲染的性能并降低内存消耗。

(3)深度结合 ArkCompiler 3.0 的方舟编译器和方舟运行时,提升语言的执行性能和跨语言通信能力。

(4)在工具方面,针对新一代的声明式 UI 开发范式构建了新的编译工具链和预览引擎,提供了所见即所得的实时预览机制。

另外,在 ArkUI 3.0 框架中,类 Web 范式会继续保留,即类 Web 范式和新一代的声明式 UI 范式都可以支持,可以各自独立使用,但不能混用。

三、ArkUI 3.0 的关键特性

接下来我们展开详细介绍一下 ArkUI 3.0 的关键特性。

1. 新一代的声明式 UI 开发范式

具体而言,ArkUI 3.0 中的新一代声明式 UI 开发范式,主要特征如下:

(1)基于 TypeScript 扩展的声明式 UI 描述语法,提供了类自然语言的 UI 描述和组合。

(2)开箱即用的多态组件。多态是指 UI 描述是统一的,UI 呈现在不同类型设备上会有所不同。比如 Button 组件在手机和手表会有不同的样式和交互方式。

(3)多维度的状态管理机制,支持灵活的数据驱动的 UI 变更。

下面我们以一个具体的示例来说明新一代声明式 UI 开发范式的基本组成。如图 3 所示的代码示例,UI 界面会显示一个“Hello World”的文本和一个“Click me”按钮。当用户点击“Click me”按钮时,字符串变量 myText 的值会从“World”变为“ACE”,文本最终显示为“Hello ACE”。

图 3 声明式 UI 开发范式的基本概念

以上示例中所包含的声明式 UI 开发范式的基本组成说明如下:

  • 装饰器:用来装饰类、结构体、方法以及变量,赋予其特殊的含义,如上述示例中 @Entry、@Component、@State 都是装饰器。@Component 表示这是个自定义组件;@Entry 则表示这是个入口组件;@State 表示组件中的状态变量,这个状态变化会引起 UI 变更。

  • 自定义组件:可复用的 UI 单元,可组合其它组件,如上述被 @Component 装饰的 struct Hello。

  • UI 描述:声明式的方式来描述 UI 的结构,如上述 build()方法内部的代码块。

  • 内置组件:框架中默认内置的基础和布局组件,可直接被开发者调用,比如示例中的 Column、Text、Divider、Button。

  • 事件方法:用于添加组件对事件的响应逻辑,统一通过事件方法进行设置,如跟随在 Button 后面的 onClick()。

  • 属性方法:用于组件属性的配置,统一通过属性方法进行设置,如 fontSize()、width()、height()、color()等,可通过链式调用的方式设置多项属性。

上述示例中,用 @State 装饰过的变量 myText,包含了一个基础的状态管理机制,即 myText 的值的变化,会引起相应的 UI 变更(Text 组件)。ArkUI 3.0 还提供多维度的状态管理机制。和 UI 相关联的数据,不仅仅在组件内使用,还可以在不同组件层级间传递,比如父子组件之间,爷孙组件之间,也可以是全局范围内的传递,还可以是跨设备传递。另外,从数据的传递形式来看,可以分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和 UI 的联动。

ArkUI 采用嵌入式领域特定语言(embedded Domain Specific Language, eDSL)的形式,结合宿主语言能力实现 UI 开发。通过 eDSL,结合语法糖或者语言原生的元编程能力,设计了统一的 UI 开发范式,并能够结合不同语言来实现应用的逻辑处理部分。

2. 关键渲染性能

下面通过一个简单的示例代码,为大家讲述从代码到 UI 显示的整体渲染流程。如图 4 所示,此示例会在 UI 界面显示一个“Click me”按钮,按钮下面同步显示按钮的点击次数。当用户点击按钮时,下面的点击次数会相应增加。

图 4 整体渲染流程

整个渲染过程分为两个阶段:

(1)初始显示流程(步骤①~⑤)

① 源代码通过相应的工具链,编译为带有类型标志的目标文件,同时也包含了如何创建 UI 结构信息的指令流。

② 通过跨语言调用并生成了 C++层 Component 树(UI 描述层)。

③ 通过 Component 树进一步生成 Element 树。Element 是 Component 的实例,表示一个具体的组件节点,它形成的 Element 树负责维持界面在整个运行时的树形结构,方便计算更新时的局部更新算法等。

④ 对于每个可显示的 Element 都会为其创建对应的 RenderNode。RenderNode 负责一个节点的显示信息,它形成的 Render 树维护着整个界面渲染需要用到的信息,包括位置、大小、绘制命令等。后续的布局、绘制都是在 Render 树上进行的。

⑤ 实现真正的渲染并显示绘制结果。

(2)按钮被点击后的显示流程(步骤⑥~⑪)

⑥ 点击事件传递到组件,组件的 onClick 事件方法被触发执行。

⑦ 由于 onClick 事件方法中 @State 注解过的变量改变了,相应 getter/setter 函数会被触发。

⑧ 状态管理模块定位出关联的 UI 组件。

⑨ 状态管理模块更新相应的 Element 树的信息。

⑩ 更新相应的 UI 组件的渲染信息。

⑪ 界面显示,与⑤类似。

整个渲染过程中所需的关键能力,除了极简的开发范式本身,主要包含以下三个部分:

  • 编译优化以及跨语言调用。结合目标文件中的类型信息标志,ArkCompiler 会实现相应的代码优化。另外,ArkCompiler 也提供了高效的 JS/TS -> C++跨语言调用机制。

  • 扁平化渲染机制以及小对象组合机制。组件信息的结构在前后端有基本一致的表示,进一步减少了转换开销,实现了扁平化的渲染。同时,UI 组件内部都是通过轻量化对象来按需组合,内存消耗也进一步降低。

  • 状态管理机制。通过监听变量的存取操作,实现数据变化的自动化感知并计算出相应的最小化 UI 组件更新范围,实现高效的 UI 变更。

除此之外,长列表渲染是一种典型的应用场景,里面可能会涉及到大量的数据,如果处理不当,会引起极大影响性能以及资源占用。ArkUI 3.0 针对这类常用的场景,提供了一种 LazyForEach 懒加载机制,会自动根据具体情况计算出合适的渲染数据,实现数据的按需加载,从而提升 UI 刷新效率。LazyForEach 可以结合常用的列表类组件(比如 List、Grid 等)灵活配合使用。

3. 高级 UI 组件库

高级的 UI 组件库可以进一步助力高效的应用开发。HarmonyOS 的欧洲研发团队基于 ArkUI 3.0,构建了一些高阶组件示例,比如:常用的图表类组件、瀑布流布局组件等。开发者可以通过几行代码就可以实现复杂酷炫的 UI 效果,比如自适应的图片增删、行列变化,以及相应的酷炫动效效果。

示例如下:

图 5 图表组件

图 6 瀑布流布局组件

4. 多设备开发

除了 UI 开发套件,ArkUI 3.0 围绕着多设备开发,还提供了多维度的方案,进一步简化开发:

(1)基础能力层:包括基础的分层参数配置(比如色彩、字号、圆角、间距等),栅格系统,原子化布局能力(比如拉伸、折行、隐藏等)。

(2)零部件组件层:包括多态控件,统一交互能力,以及在此基础上的组件组合。

(3)面向典型场景:提供分类的页面组合模板以及示例代码。

关于多设备开发,后面我们会有更详细的文章介绍,请大家持续关注。

5. 实时预览机制

整个开发流程中还有一个很重要的方面——预览能力,即可以在 PC 上通过 IDE(集成开发环境)就可以实时看到应用的渲染效果,而无需通过具体设备来部署运行。预览的关键需求主要包括:

(1)一致性渲染:和目标设备一致的 UI 呈现效果。

(2)实时预览 &双向预览:改动相应的代码,实时呈现出相应 UI 效果。另外,代码能够和 UI 双向联动,代码改动的同时 UI 也实时变更,UI 改动的同时代码也相应地变更。

(3)多维度预览:页面级预览、组件级预览、多设备预览。

以上这些能力都需要 UI 编程框架具备相应的基础设施才能达成。ArkUI 3.0 的预览器的整体架构如下图所示:

图 7 ArkUI 3.0 的预览器架构

ArkUI 3.0 基于底层的画布通过自绘制实现了不同平台上一致化的渲染体验,并通过渲染侧的跨平台对接层完成了整体渲染效果。另外,ArkUI 3.0 通过实时代码变化检测和增量编译机制,再配合前面所提到的高效渲染性能,实现了实时编写预览。

通过 ArkUI 3.0 的基础设施,结合 IDE 可视化工具(即预览器前端),就实现了上面的实时预览、双向预览等能力,进一步提升了开发者的开发效率。

四、结束语

总体而言,UI 编程框架在应用开发中起了至关重要的作用。目前,拥有全新开发范式的新一代的 UI 框架——ArkUI 3.0 走出了坚实的第一步,并已开始支撑更多的关键应用。接下来,除了基础设施的持续完善,我们会重点支持生态扩展,主要包括高级 UI 能力的提升,比如三方地图,游戏的融合,以及 Web 能力增强等。同时,我们也会围绕跨设备、性能体验持续地创新。欢迎广大的开发者加入进来,一起探索,一起改进,共建万物互联的应用生态!未来,有迹可循!

用户头像

每一位开发者都是华为要汇聚的星星之火 2021.10.15 加入

提供HarmonyOS关键技术解析、版本更新、开发者实践和活动资讯,欢迎各位开发者加入HarmonyOS生态,一起创造无限可能!

评论

发布
暂无评论
HDC技术分论坛:HarmonyOS新一代UI框架的全面解读