「Android渲染」图像是怎样显示到屏幕上的?

我们每天花很多时间盯着手机屏幕,不知道你有没有好奇过:

手机屏幕上的这些东西是怎么显示出来的?

这时候来了一位Android程序员(当然也可以是iOS或者是前端程序员)说: 这里显示的其实是一个View树,我们看到的都是大大小小的View。

。。。听起来很有道理,我们也经常指着屏幕说这个View怎么怎么样,可问题又来了:

屏幕认识View吗?
我们把一个View发给屏幕,它就显示出来了?

程序员老兄又来了: 屏幕当然不能识别View,它作为一个硬件,只能根据收到的数据改变每个像素单元的数据,这样整体来看,用户就发现屏幕上的内容变化了。至于View的内容是如何一步一步转化成屏幕可是识别的数据的,简单讲可以分成三步:

  1. 准备材料
  2. 画出来
  3. 显示到屏幕

。。。听起来很有道理,可问题又来了:

这也太简单了吧,能详细一点吗?

那可就说来话长了。。。

1. 准备材料

对于measure layoutdraw,Android工程师(大都)非常熟悉,我们常常在执行了onDraw()方法后,一个让人自豪的自定义View就显示出来了。在实际的Android绘制流程中,第一步就是通过measure layoutdraw这些步骤准备了下面的材料:

  • 画什么
  • 画的参数

画什么

在Android的绘制中,我们使用Canvas API进行来告诉表示画的内容,如drawCircle() drawColor() drawText() drawBitmap()等,也是这些内容最终呈现在屏幕上。

画的参数

  • 画的坐标

    坐标系: Android图像坐标系以左上角为0点,x轴左负右正,y轴上负下正,z轴内负外正;

    Viewlayout基准点是父容器的左上角,View的draw内容基准点是View的左上角。

    根节点父容器是当前WindowDecorView,它的布局信息由WindowManger来管理。

    到此,当前应用所有View放在哪个位置就确定了。

  • 画的层级(重叠时的覆盖关系)

    View之间并不是井水不犯河水,经常出现重叠的情况,重叠时该怎样覆盖和显示正确的View大体遵循以下规则:

    • 指定z-order情况下,数值最大的显示在最上层,剩下的降序显示。
    • 在没有指定z-order的情况下,子View覆盖父容器,相同父容器View后添加的显示在最上层。
  • 特定参数

    不同的方法需要的参数不同,比如drawCircle()会有圆心和半径,drawText()需要对应的text资源,drawBitmap()需要对应的Bitmap资源等等。

在当前应用中,View树中所有元素的材料最终会封装到DisplayList对象中(后期版本有用RenderNodeDisplayList又做了一层封装,实现了更好的性能),然后发送出去,这样第一阶段就完成了。

当然就有一个重要的问题:

这个阶段怎么处理Bitmap呢?

会将Bitmap复制到下一个阶段(准确地讲就是复制到GPU的内存中)。
现在大多数设备使用了GPU硬件加速,而GPU在渲染来自Bitmap的数据时只能读取GPU内存中的数据, 所以需要赋值Bitmap到GPU内存,这个阶段对应的名称叫Sync&upload。另外,硬件加速并不支持所有Canvas API,如果自定义View使用了不支持硬件加速的Canvas API(参考Android硬件加速文档),为了避免出错就需要对View进行软件绘制,其处理方式就是生成一个Bitmap,然后复制到GPU进行处理。

这时可能会有问题:如果Bitmap很多或者单个Bitmap尺寸很大,这个过程可能会时间比较久,那有什么办法吗?

当然有(做作。。。)

  • 预上传: Bitmap.prepareToDraw()(from Android 7.0 - Nougat)

  • 使用Hardware-Only Bitmap(from Android 8.0 - Oreo)

    从Android 8.0 开始,支持了Hardware-Only Bitmap类型,这种类型的Bitmap的数据只存放在GPU内存中,这样在Sync&upload阶段就不需要upload这个Bitmap了。使用很简单,只需要将Options.inPreferredConfig赋值为Bitmap.Config.HARDWARE即可。

    这种方式能实现特定场景的极致性能,提供便利的同时,这种Bitmap的某些操作是受限的(毕竟数据

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值