共计 10025 个字符,预计需要花费 26 分钟才能阅读完成。
作者:zhiqiang、sunfei、wanglei,华为软件开发工程师
UI 框架简介以及业界发展趋势
UI,即用户界面,次要蕴含视觉(比方图像、文字、动画等可视化内容)以及交互 (比方按钮点击、列表滑动、图片缩放等用户操作)。UI 框架,则是为开发 UI 而提供的 基础设施,比方视图布局,UI 组件,事件响应机制等。
从操作系统平台反对形式来看,UI 框架个别可分为 原生 UI 框架 和跨平台 UI 框架 两种。
1.原生 UI 框架。这个个别是指操作系统自带的 UI 框架,典型的例子包含 iOS 的 UI Kit,Android 的 View 框架等。这些 UI 框架和操作系统深度绑定,个别只能运行在相应的操作系统上。性能,性能,开发调测等方面和相应的操作系统联合较好。
2.跨平台 UI 框架。这个个别是指能够在不同的平台(OS)上运行的独立的 UI 框架。典型例子包含 HTML5 以及基于 HTML5 延长进去的前端框架 React Native,以及 Google 的 Flutter 等。跨平台 UI 框架的指标是代码只需一次编写,通过大量批改甚至不批改,能够部署到不同的操作系统平台上。当然,实现跨平台也是有代价的,因为不同平台存在差异性(比方 UI 的出现形式差别,API 差别等等),导致 UI 框架自身的架构实现,以及和不同平台的交融都有不小的挑战。
从编程形式上来看,UI 框架个别可分为 命令式 UI 框架 和申明式 UI 框架 两种:
1.命令式 UI 框架。过程导向 – 通知“机器”具体步骤,命令“机器”依照指定步骤去做。比方 Android 原生 UI 框架(View 框架)或 iOS 的 UIKit,提供了一系列的 API 让开发者间接操控 UI 组件 - 比方定位到某个指定 UI 组件,进行属性变更等。这种形式的长处是开发者能够管制具体的实现门路,经验丰富的开发者可能写出较为高效的实现。不过这种状况下,开发者需理解大量的 API 细节并指定好具体的执行门路,开发门槛较高。具体的实现成果上,也高度依赖开发者自身的开发技能。另外,因为和具体实现绑定较紧,在跨设施状况下,灵活性和扩展性绝对无限。
2.申明式 UI 框架。后果导向 – 通知“机器”你须要什么,机器负责怎么去做。比方 Web 前端框架 Vue, 或 iOS 的 SwiftUI 等,框架会依据申明式语法的形容,渲染出相应的 UI,同时联合相应编程模型,框架会依据数据的变动来自动更新相应的 UI。
这种形式的长处是开发者只需形容好后果,相应的实现和优化由框架来解决。另外,因为后果形容和具体实现拆散,实现形式绝对灵便同时容易扩大。不过这种状况下,对框架的要求较高,须要框架有齐备的直观的形容能力并可能针对相应的形容信息实现高效的解决。
UI 框架是利用开发的外围组成部分。纵观业界 UI 框架,其次要发展趋势体现为:
1. 从命令式 UI 往申明式 UI 倒退
比方 iOS 中的 UIKit 到 SwiftUI, Android 中的 View 到 Jetpack Compose。
这样能够实现更加直观便捷的 UI 开发。
2.UI 框架和语言运行时深度交融
SwiftUI,Jetpack Compose,Flutter 都利用了各自的语言个性 – 比方在 UI 形容方面,SwiftUI 中的 Swift 语言,Jetpack Compose 中的 Kotlin 语言都精简了 UI 形容语法;在性能方面,Swift 通过引入轻量化构造体等语言个性更好的实现内存疾速调配和开释,Flutter 中 Dart 语言则在运行时专门针对小对象内存治理做相应优化等。
3. 跨平台(OS)能力
跨平台(OS)能力能够让一套代码复用到不同的 OS 上,次要是为了晋升开发效率,升高开发成本。不过这外面也有一系列的挑战,比方运行在不同平台上的性能问题,能力和渲染成果的一致性问题等。业界在这方面也是一直的演进,次要有几种形式:
1.JS/Web 计划,比方 HTML5 利用 JS/Web 的标准化生态,通过相应的 Web 引擎实现跨平台指标;
2.JS+Native 混合形式,比方 React Native、Weex 等, 联合 JS 桥接到原生 UI 组件的形式实现了一套利用代码可能运行到不同 OS 上;
3. 平台无关的 UI 自绘制能力 + 新的语言,比方 Flutter,整个 UI 基于底层画布由框架层来绘制,同时联合 Dart 语言实现残缺的 UI 框架。Flutter 从设计之初就是将跨平台能力作为重要的竞争力去吸引更多的开发者。
另外,乏味的是,局部原生开发框架也开始往跨平台演进。比方,Android 原生的开发框架 Jetpack Compose 也开始将跨 OS 反对作为其中的指标,打算将 Compose 拓展到桌面平台,比方 Windows,MacOS 等。
此外,随着智能设施的遍及,多设施场景下,设施的状态差别(屏幕大小、分辨率,形态, 交互模式等),以及设施的能力差异(从百 K 级内存到 G 级内存设施等),以及利用须要在不同设施间协同,这些都对 UI 框架以及利用开发带来了新的挑战。
ACE UI 框架是什么
ACE 全称是 Ability Cross-platform Environment (元能力跨平台执行环境)。是华为设计的利用在 HarmonyOS 上的 UI 框架。ACE UI 框架联合 HarmonyOS 的根底运行单元 Ability,语言和运行时,以及各种平台(OS)能力 API 等独特形成 HarmonyOS 利用开发的根底,实现了跨设施散布式调度,以及原子化服务免装置等能力。
ACE 提供两种开发语言以供不同开发者进行抉择,别离为 Java 语言和 JavaScript 语言,其中 Java 仅反对在内存较大的设施上应用如大屏、手机、平板等设施应用,而 JavaScript 反对在百 K 级到 G 级设施上应用。
在多设施场景下,因为不同的设施状态以及设施能力的微小差别,目前业界还 没有任何一个 UI 框架可能较好的解决相应的问题。
所以ACE UI 框架的整体设计思路是:
1. 建设分层机制,引入高效的 UI 根底后端,并可能与 OS 平台解耦,造成统一化的 UI 体验
2. 通过多前端的形式扩大利用生态,并联合申明式 UI,在开发效率上继续演进
3. 框架层对立联合语言以及运行时,分布式,组件化设计等,围绕跨设施,进一步晋升体验
ACE 将利用的 UI 界面进行解析,通过创立后端具体 UI 组件、进行布局计算、资源加载等解决后生成具体绘制指令,并将绘制命令发送给渲染引擎,渲染引擎将绘制指令转换为具体屏幕像素,最终通过显示设施将利用程序转换为可见的界面成果展现给用户。
ACE UI 框架的整体架构如下图所示,次要由前端框架层、桥接层、引擎层和平台形象层四大局部组成,上面咱们一一介绍。
1. 前端框架层
该层次要包含相应的开发范式(比方支流的类 Web 开发范式),组件 /API,以及编程模型MVVM(Model-View-ViewModel)。其中 Model 是数据模型层,代表了从数据源读取到的数据;View 是视图 UI 层,通过肯定的模式把零碎中的数据向用户出现进去;ViewModel: 视图模型层,是数据和视图之间的桥梁。它双向绑定了视图和数据,使得数据的变更可能及时在视图上出现,用户在视图上的批改也可能及时传递给后盾数据,从而实现数据驱动的 UI 主动变更。
开发范式能够扩大,来反对生态倒退。不同的开发范式能够对立适配到底层的引擎层
2. 桥接层
该层次要是作为一个中间层,实现前端开发范式到底层引擎(包含 UI 后端,语言 & 运行时)的对接
3. 引擎层
该层次要蕴含两局部:UI 后端引擎和语言执行引擎。
1. 由 C ++ 构建的UI 后端引擎,包含 UI 组件、布局视图、动画事件、自绘制渲染管线和渲染引擎。
在渲染方面,咱们尽可能把这部分组件设计得小而灵便。这样的设计,为不同前端框架提供灵便的 UI 能力,这部分通过 C ++ 组件组合而成。通过底层组件的按需组合,布局计算和渲染并行化,并联合下层开发范式实现了视图变动最小化的部分更新机制,从而实现高效的 UI 渲染。
除此之外,引擎层还提供了组件的渲染管线、动画、主题、事件处理等根底能力。目前复用了 Flutter 引擎提供根底的图形渲染能力、字体治理、文字排版等能力,底层应用 Skia 或其余图形库实现,并通过 OpenGL 实现 GPU 硬件渲染减速
在多设施 UI 适配方面,通过多种原子化布局能力(主动折行、暗藏、等比缩放等),多态 UI 控件(形容对立,体现形式多样),以及对立交互框架(不同的交互方式归一到对立的事件处理)来满足不同设施的状态差异化需要。
另外,引擎层也蕴含了能力扩大基础设施,来实现自定义组件以及零碎 API 的能力扩大
2. 语言 & 运行时 执行引擎。可依据须要切换到不同的运行时执行引擎,满足不同设施的能力差异化需要
4. 平台形象层
该层次要是通过平台形象,将平台依赖聚焦到底层画布,通用线程以及事件机制等多数必要的接口上,为跨平台打造了相应的基础设施,并可能实现统一化 UI 渲染体验。
相应的,配套的开发者工具(HUAWEI DevEco Studio)联合 ACE UI 的跨平台渲染基础设施,以及自适应渲染,可做到和设施比拟统一的渲染体验以及多设施上的 UI 实时预览。
另外,ACE UI 框架还设计了可伸缩的架构,即前端框架、语言运行时、UI 后端等都做理解耦,能够有不同的实现。这样就具备可部署到百 K 级内存的轻量级设施的能力,如下所示:
在 ACE UI 的轻量化实现中,通过前端框架外围下沉 C ++ 化,减小 JS 局部的内存占用,应用 C ++ 进行更为严格的内存调配与治理,并且采纳更为轻量的 JS 引擎,UI 局部采纳轻量的 UIKit 并联合轻量图形引擎,达到内存十分轻量占用的指标。接口能力保障是全量能力的子集,这样能够保障轻量化设施上可执行的利用,能够在更高等级的设施上执行,而无需从新开发。这也就是采纳 ACE JS 开发范式的劣势所在,采纳对立的开发范式进行利用开发后,开发者无需关怀具体运行时的前端框架、JS 引擎与后端 UI 组件,依据运行平台不同,采纳最佳的模块,保障了利用在不同平台都可具备最佳的运行性能。不过因为轻量级设施上的资源限度,所反对的 API 能力绝对无限,但公共局部的 API 是齐全共通的。
综上所述,ACE UI 框架具备如下特点:
1.反对支流的语言生态 – JavaScript
2.反对类 Web 开发范式,MVVM 机制。并在架构上可反对多前端开发范式,进一步简化开发
3. 通过对立的 UI 后端,实现高性能以及跨平台统一化的渲染体验
4. 通过多态 UI、原子化布局、对立交互,以及可伸缩的运行时设计,进一步升高不同设施状态下的 UI 开发门槛,并可能通过对立的开发范式,实现一套代码跨设施部署(笼罩百 K 级到 G 级内存设施)
ACE UI 框架渲染流程解析
接下来咱们通过一个手机侧 ACE JS 利用渲染流程的残缺流程来介绍 ACE UI 框架的具体渲染技术。
1)线程模型
ACE JS 利用启动时会创立一系列线程,造成独立的线程模型,以实现高性能的渲染流程。
每个 ACE JS 利用的过程,蕴含惟一一个 Platform 线程和若干后盾线程组成的异步工作线程池:
•Platform 线程:以后平台的主线程,也就是利用的主线程,次要负责平台层的交互、利用生命周期以及窗口环境的创立
•后盾线程池: 一系列后台任务,用于一些低优先级的可并行异步工作,如网络申请、Asset 资源加载等。除此之外,每个实例还包含一系列专有线程
•JS 线程:JS 前端框架的执行线程,利用的 JS 逻辑以及利用 UI 界面的解析构建都在该线程执行
•UI 线程: 引擎的外围线程,组件树的构建以及整个渲染管线的外围逻辑都在该线程:包含渲染树的构建、布局、绘制以及动画调度
•GPU 线程: 古代的渲染引擎,为了充分发挥硬件性能,都反对 GPU 硬件加速,在该线程上,会通过零碎的窗口句柄,创立 GPU 减速的 OpenGL 环境,负责将整个渲染树的内容光栅化,间接将每一帧的内容渲染合成到该窗口的 Surface 上并送显
•IO 线程: 次要为了异步的文件 IO 读写,同时该线程会创立一个离屏的 GL 环境,这个环境和 GPU 线程的 GL 环境是同一个共享组,能够共享资源,图片资源解码的内容可间接在该线程上传生成 GPU 纹理,实现更高效的图片渲染
每个线程的作用,在后续的渲染流程中还会进一步提到。
2)前端脚本解析
ACE UI 框架反对不同的开发范式,能够对接到不同的前端框架上。
以类 Web 开发范式为例,开发者开发的利用,通过开发工具链的编译,会生成引擎可执行的 Bundle 文件。利用启动时,会将 Bundle 文件在 JS 线程上进行加载,并且将该内容作为输出,供 JS 引擎进行解析执行,最终生成前端组件的结构化形容,并建设数据绑定关系。例如蕴含若干简略文本的利用会生成相似下图的树形构造,每个组件节点会蕴含该节点的属性及款式信息。
3)渲染管线构建
如上图,前端框架的解析后,依据具体的组件标准定义向 前端框架对接层 申请创立 ACE 渲染引擎提供的组件。
前端框架对接层 通过 ACE 引擎层提供的 Component 组件实现前端组件定义的能力。Component 是一个由 C ++ 实现的 UI 组件的申明式形容,形容了 UI 组件的属性及款式,用于生成组件的实体元素。每一个前端组件会对接到一个 Composed Component,示意一个组合型的 UI 组件,通过不同的子 Component 组合,结构出前端对应的 Composed 组件。每个 Composed 组件是前后端对接的一个根底的更新单位。
以下面的前端组件树为例,每个节点会应用一组 Composed 组件进行组合形容,对应关系如下图,该对应关系只是一个示例,理论场景的对应关系可能会更简单。
有了每个前端节点对应的 Component,就造成了一个实现 Page 的形容构造,告诉渲染管线挂载新的页面。
在 Page 挂载之前,渲染管线曾经提前创立了几个要害的外围构造,Element 树和 Render 树:
Element 树,Element 是 Component 的实例,示意一个具体的组件节点,它造成的 Element 树负责维持界面在整个运行时的树形构造,不便计算部分更新算法。另外对于一些简单的组件,在该数据结构上会实现一些对子组件逻辑上的治理。
Render 树,对于每个可显示的 Element 都会为其创立对应的 RenderNode,它负责一个节点的显示信息,它造成的 Render 树保护着整个界面的渲染须要用到的信息,包含它的地位、大小、绘制命令等,界面后续的布局、绘制都是在 Render 树上进行的。
当利用启动时,最后造成的 Element 树只有几个根底的几节点,个别包含 root、overlay、stage,别离作用如下:
RootElement:Element 树的根节点,仅仅负责全局背景色的绘制
OverlayElement:一个全局的悬浮层容器,用于弹窗等全局绘制场景的治理
StageElement:一个 Stack 容器,作为全局的“舞台”,每个加载实现的页面都要挂载到这个“舞台”下,它治理利用的多个页面之间的转场动效等。
在 Element 树创立的过程中,也会同步的把 Render 树也创立起来,初始状态如下图:
以后端框架对接层告诉渲染管线筹备好了页面,在下一个帧同步信号(VSync)到来时,就会在渲染管线上进行页面的挂载,具体流程就是通过 Component 来实例化生成 Element 的过程,创立胜利的 Element 同步创立对应的 RenderNode:
如上图所示,指标要将整个 Page 的 Component 形容挂载到 StageElement 上,如果以后 Stage 下还未有任何 Element 节点,就会递归一一节点生成 Component 对应的 Element 节点。对于组合类型的 ComposedElement,则同时会把 Element 的援用记录到一个 Composed Map 中,不便后续更新时疾速查找。对于可见类型的容器节点或渲染节点,则会创立对应的 RenderNode,并挂在 Render 树上。
当生成了以后页面的 Element 树和 Render 树,页面渲染构建的残缺过程就完结了。
4)布局绘制机制
接下来就进入了布局和绘制的阶段,布局和绘制都是在 Render 树上进行的。每个 RenderNode 都会实现本人的布局算法和绘制办法。
布局
布局的过程就是通过各类布局的算法计算出每个 RenderNode 在绝对空间上的实在大小和地位。
如下图所示,当某个节点的内容发生变化时,就会标记本人为 needLayout,并始终向上标记到布局边界(ReLayout Boundary),布局边界是从新布局的一个范畴标记,个别状况下,如果一个节点的布局参数信息(LayoutParam)是强束缚的,例如它布局冀望的最大尺寸和最小尺寸是雷同的,那么它就能够作为一个布局边界。布局是个深度优先遍历的过程。从布局边界开始,父节点自顶向下将 LayoutParam 传给子节点,子节点自底向上据此计算失去尺寸大小和地位,
对于每个节点来说,布局分为三个步骤:
1. 以后节点递归调用子节点的 layout 办法,并传递布局的参数信息(LayoutParam),蕴含了布局冀望的最大尺寸和最小尺寸等
2. 子节点依据布局参数信息,应用本人定义的布局算法来计算本人的尺寸大小
3. 以后节点获取子节点布局后的大小,再依据本人的布局算法来计算每个子节点的地位信息,并将绝对地位设置给子节点保留
根据上述的流程,一次布局遍历实现后,每个节点的大小和地位就都计算出来了,能够进行下一步的绘制。
绘制
同布局一样,绘制也是一个深度遍历的过程,遍历调用每个 RenderNode 的 Paint 办法,此时的绘制只是依据布局算进去的大小和地位,在以后绘制的上下文记录每个节点的绘制命令。
为什么是记录命令,而不是间接绘制渲染呢?在古代的渲染引擎中,为了充沛应用 GPU 硬件加速的能力,个别都会应用 DisplayList 的机制,绘制过程中仅仅将绘制的命令记录下来,在 GPU 渲染的时候对立转成 OpenGL 的指令执行,能最大限度的进步图形的解决效率。所以在下面提到的绘制上下文中,会提供一个能够记录绘制命令的画布(Canvas)。每一个独立的绘制上下文能够看作是一个图层。
为了进步性能,这里引入了图层(Layer)的概念。通常绘制会将渲染内容分为多个层进行减速。对于会频繁变动的内容,将其独自创立一个图层,那么这个独立图层的频繁刷新就不用导致其余内容从新绘制,从而达到晋升性能并缩小功耗的成果,同时还能够反对 GPU 缓存等优化。每个 RenderNode 都能够决定本人是否须要独自分层。
如下图所示,绘制流程会从须要绘制的节点中,筛选最近的且须要分层的节点开始,自顶向下的执行每个节点的 Paint 办法。
对每个节点,绘制分为四个步骤:
1. 如果以后节点须要分层,那么须要创立一个新的绘制上下文,并提供能够记录绘制命令的画布
2. 在以后的画布上记录背景的绘制命令
3. 递归调用子节点的绘制办法,记录子节点的绘制命令
4. 在以后的画布上记录前景的绘制命令
一次残缺的绘制流程完结后,咱们会失去一棵残缺的 Layer 树,Layer 树上蕴含了这一帧残缺的绘制信息:包含每一层的地位、transform 信息、Clip 信息、以及每个元素的绘制命令。下一步就要通过光栅化和合成的过程,将这一帧的内容显示到界面。
5)光栅化合成机制
在下面的绘制流程完结后,会告诉 GPU 线程开始进行合成的流程。
如上图所示,UI 线程(UI Thread)在渲染管线中的输入是 LayerTree,它相当于一个生产者,将生产的 LayerTree 增加到渲染队列中。GPU 线程(GPU Thread)的合成器(Compositor)相当于消费者,每个新的渲染周期中,合成器会从渲染队列中获取一个 LayerTree 进行合成生产。
对于须要缓存的 Layer, 还要执行光栅化生成 GPU 纹理,所谓光栅化就是将 Layer 外面记录的命令进行回放,生成每个实体的像素的过程。像素是存储在纹理的图形内存中。
合成器会从零碎的窗口中获取以后的 Surface,将每个 Layer 生成的纹理进行合成,最终合成到以后 Surface 的图形内存(Graphic Buffer)中。这块内存中存储的就是以后帧的渲染后果内容。最终还须要将渲染后果提交到零碎合成器中合成显示。零碎的合成过程如下图所示:
当 GPU 线程的合成器实现一帧的合成后,会进行一次 SwapBuffer 的操作,将生成的 Graphic Buffer 提交到与零碎合成器建设的帧缓冲队列(Buffer Queue)中。零碎合成器会从各个生产端获取最新的内容进行最终的合成,以上图为例,零碎合成器会将以后利用的内容和零碎其它的显示内容,例如 System UI 的状态栏、导航栏,进行一次合成,最终写入到屏幕对应的帧缓冲区(Frame Buffer)中。液晶屏的驱动就会从缓冲区读取内容进行屏幕的刷新,最终将内容显示到屏幕上。
6)部分更新机制
通过下面 1~5 的流程,实现了首次残缺的渲染的流程,在后续的运行中,例如用户输出、动画、数据扭转都有可能造成页面的刷新,如果只是局部元素产生了变动,并不需要全局的刷新,只须要启动部分更新即可。那么部分更新是怎么做到的?上面咱们介绍一下部分 更新的流程。
以上图为例,JS 在代码中更新了数据,通过数据绑定模块会主动触发前端组件属性的更新,而后通过 JS 引擎异步发动更新属性的申请。前端组件会依据变更的属性,构建一组新的 Composed 的补丁(Patch),作为渲染管线更新的输出。
如上图所示,在下一个 VSync 到来时,渲染管线会在 UI 线程开始更新的流程。通过 Composed 补丁的 Id,在 ComposedMap 中查问到对应的 ComposedElement 在 Element 树上的地位。通过补丁对 Element 树进行更新。以 ComposedElement 为起始,逐层进行比照,如果节点类型统一则间接更新对应属性和对应的 RenderNode,如果不统一则从新创立新的 Element 和 RenderNode。并将相干的 RenderNode 标记为 needLayout 和 needRender。
如上图所示,依据标记须要从新布局和从新渲染的 RenderNode,从最近的布局边界和绘制图层进行布局和绘制的流程,生成新的 Layer 树,只须要从新生成变更 RenderNode 对应的 Layer 即可。
如上图所示,接下来,依据刷新后的 Layer 树作为输出,在 GPU 线程进行光栅化和合成。对于曾经缓存的 Layer 则不须要从新光栅化,合成器只须要将已缓存的 Layer 和未缓存或更新的 Layer 从新合成即可。最终通过零碎合成器的合成,就会将新一帧的内容显示。
以上就是一个 ACE JS 利用的渲染及更新的流程。最初,通过两张流程图回顾一下整体的流程:
理解完 ACE JS 利用的渲染及更新的流程,如果大家想理解更多对于 HarmonyOS UI 框架如何解决设施状态差别带来的开发挑战和利用示例,可参考咱们之前推出的内容:解密 HarmonyOS UI 框架:
https://mp.weixin.qq.com/s/0R…。
ACE UI 框架目前的成熟度以及演进
截至目前,ACE UI 框架已商用落地了华为静止手表,华为智能手表,华为智慧屏,华为手机,华为平板等一系列产品。应用场景包含日历、出行、健身、实用工具等各类利用,手机 - 设施碰一碰全品类的利用,以及往年六月份公布的 HarmonyOS 中各类的服务卡片 - 图库、相机等。另外,在开发调测方面,开发者工具(HUAWEI DevEco Studio)中也集成了 ACE UI 框架,反对在 PC 端(MacOS,Windows)上的开发调测,实时预览(包含实时多设施预览,组件级预览,双向预览等),实现了在 PC 上和设施上统一的渲染体验。
将来,面向开发者的极简开发,面向消费者的晦涩酷炫的体验,以及可能高效在不同设施不同平台上部署,ACE UI 框架会持续沿着精简开发和高性能两个方面演进,联合语言更进一步简化开发范式,联合运行时在跨语言交互,类型优化等方面进一步加强性能体验,联合分布式能力将编程模型从 MVVM 演进到分布式 MVVM(Distributed Model-View-ViewModel)等。采纳类自然语言的申明式 UI 形容进行界面搭建,编程语言也进一步凋谢,将来思考向 TS 进行演进,从动效、布局和性能方面进一步晋升用户应用体验。
当然,利用生态还会波及更多的方面,比方三方插件的凋敝,跨 OS 平台的扩大,更具翻新的分布式体验等等。ACE UI 框架还很年老,期待和泛滥开发者一起,重点围绕着多设施组成的超级终端的新兴场景,一直打磨欠缺,独特构建当先的利用体验和生态!
目前 HarmonyOS 的线上开发体验已上架,欢送大家在线体验。ACE JS 框架曾经进驻开源社区,欢送关注与共建,期待诸位一起共建咱们的开发框架,有开发过程中的疑难和对 HarmonyOS 开发的好的倡议欢送登录论坛,咱们一起探讨。论坛链接可拜访:
https://developer.huawei.com/…,
开源社区:https://gitee.com/openharmony…