跨平台 UI 框架原理及展望,2024Android春招面试真题

本文探讨了UI框架的核心原理,包括构建Tree、排版、绘制、事件处理和动画,强调了布局算法和性能优化的重要性。作者分析了React Native和Flutter的局限性,并提出未来UI框架应具备全场景、积木式和自绘的特点,以解决开发成本、性能体验、多端一致性、动态化和包大小等问题。此外,文章提到了动态化与性能之间的矛盾,并分享了个人的UI框架设计思路。
摘要由CSDN通过智能技术生成

一般来说,渲染引擎可以设计为两个线程:UI 线程和 GPU 线程

  • UI 线程:构建 Tree、排版、绘制、事件
  • GPU 线程:合成

UI 线程的工作会比较多,是比较重的一个线程。事件放在 UI 线程的好处是显示和交互是一体的,不会存在事件发生的时候 UI 还有很多未完成的操作。典型的例子是 WebView,WebView 的事件处理是单独的线程,所以一个长列表,你可以无限滚动,如果 UI 线程跟不上,就会导致白屏问题,本质上还是线程设计的问题。

2.2.2 构建 Tree

界面上的每一个元素叫做一个 Node,每个 Node 都是由一个树形结构 Tree 来管理的。Tree 的生成可以有不同的方式,但最原子的操作无非是 CRUD(增、删、查、改),这个部分没什么好说的,实现 CRUD 的 API 即可。

2.2.3 排版

排版过程主要是「Measure」和「Layout」,Measure 主要是计算元素大小,得到 Size,Layout 主要是给元素定位,得到元素相对位置 Offset,或者绝对位置 Position,「位置 + 大小」确定了一个元素在屏幕上的显示区域。

这个过程中最复杂的是选择什么样的排版算法,不同的方式对于节点计算差别很大(例如 CSS 盒子模型有 static、absolute、relative 等排版方式)。不过无论是怎么排,最终只是「父决定子」还是「子决定父」两种类型,以下面的 DOM 结构进行说明

排版树.jpg

说明:蓝色是叶节点,红色是父节点,max-w / max-h 是最大值,w / h 是期望值,假设窗口大小是 800 x 600

  • 父决定子(fixed 固定值):节点 1 [800, 600],节点 2 [100, 50],节点 3 [50, 50],节点 4 [50, 50],节点 5 [5, 5],节点 6 [50, 50]
  • 子决定父(auto 自适应):父控件需要等所有子控件确定大小,再回溯回来确定自己大小。节点 5 [w = 800 x 20% x 10%, h = 600 x 20% x 10] = [16, 12],节点 3 由节点 4 和节点 5 共同确定,大小为 [66, 62]

上面算法中,只是计算了宽和高的情况,实际计算中还要加上盒子模型中的 margin、border、padding 的值才是正确的,而且这些值也受 max-w 和 max-h 的影响。

子决定父(auto 自适应)的这种排版方式和 Android 的 WRAP_CONTENT 意思差不多,实现方式可能不尽相同。这种方式对排版性能比较大,如果子节点大小变化,会导致父节点也变化,最坏的情况是整棵树的大小都发生变化。所以修改节点大小时刻如何进行重排?

  • 第一种:从 Root 节点开始全部重排,性能最差的方式
  • 第二种:从第一个确定大小的祖先节点重排(fix 方式)

第一种方式比较暴力,性能会最差,第二种比较折中,但如果整棵树都是 auto 的,那和第一种没区别。

Measure:每一个 Node 计算出了最终的大小。例如盒子模型,则得出了 margin[left, top, right, bottom],border[left, top, right, bottom],padding[left, top, right, bottom],content[width, height] 的实际大小。

Layout:根据计算出来的大小,设定 Offset 或者 Position

  • 相对于父节点的 Offset[x, y]
  • 相对于屏幕坐标原点的 Position[x, y]

排版过程完成,元素的「位置 + 大小」就已经确定,在屏幕上的区域也就确定了。

排版算法最高效的是 absolute 排版,全部都是「父决定子」的方式,没有回溯的过程。Flexbox 排版算法也是「父决定子」的排版算法,性能也比较好。从 React Native 的使用经验上看,基本上 Flexbox 可以满足绝大多数的业务场景,而且也是比较标准化的排版算法,是个不错的选择。自定义排版算法不建议,因为会增加很多学习成本,Android 一堆的 Layout 控件,看着就很烦,而且很多控件排版性能也很差。

2.2.4 绘制、合成

绘制(Paint)的过程就是将每个 Node 变成「图层」的过程,图层的大小是自己的 Size。这个图层并不一定是指一张内存中的 Bitmap,它只是一个虚拟概念,它可以是一些绘制操作的集合,还不一定要真正绘制到 Canvas 上。

合成(Composite),也叫光栅化,它的过程是按照图层的 z-order 排序,依次将图层绘制到同一个画布 Canvas 上,把图层合成像素。Canvas 可以是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值