View 的软件绘制和硬件绘制
View 的软件绘制和硬件绘制
开发 android 应用的时候,常有一些问题会涉及到 “硬件加速” ,例如在某个页面上打开/关闭硬件加速来解决特定问题。那么今天就简单说下具体 硬件绘制 相关的一些内容。
应用里的页面是以一棵棵 View 树表示的,其中每个 view 代表屏幕上一块内容。而实际显示的内容便是 view 绘制出来的,view 的绘制是从 view 树的逻辑控制者——也就是对应的 ViewRootImpl 对象触发的。其中包括软件绘制和硬件绘制两种方式。
当 ViewRootImpl 设置了 开启硬件加速 的时候,会使用硬件绘制的方式进行绘制,否则使用软件绘制。硬件绘制和软件绘制类似于对同一个接口的两种实现。其基本的绘制步骤都一样的,只是两种绘制方式里每个步骤实现不同。
View 的软件绘制
View 的软件绘制和硬件绘制的核心是 draw,也就是通常所说的 measure-layout-draw 中的 draw ,也就是绘制流程。即遍历 view 树,自上向下遍历依次调用 draw。其中会涉及 view 的绘制过程以及向下分发等。
在此 draw 的流程之前以及之后,需要进行一些处理。大家都知道 draw 是依赖于画布 canvas 的,canvas 只有在获取之后才可以进行 draw,并且 draw 完成后需要将 canvas 交给实际绘制到屏幕上的下一个环节。
而 View 的软件绘制和硬件绘制的差别,就在于 draw 之外的其他流程的实现,软件绘制步骤里,获取 canvas 之后,view 树可以直接接触到 canvas 对象,对其进行修改绘制。绘制完毕后,ViewRootimpl 将 canvas 交给对应的处理者绘制到屏幕上。
但是硬件绘制则不是如此,硬件绘制流程里,ViewRootImpl 并不会获取 canvas 并且让 view 树对其进行改动。而是将这个过程都交给另一个专门的类来“代理”,即不获取 canvas,使用另一个类里的 canvas;不对 view 进行绘制,将绘制动作封装成数据交给另一个类;也不进行下一步的处理,而是将下一步通知的能力也交给另一个类。这种情况下,ViewRootImpl 就只需要在 draw 的时候通知那个代理类开始工作,并且提供一些必要的信息就可以了。
这是一个解耦的操作,同时可以将 绘制 动作变得可扩展了。
View 的硬件加速
当我们在 manifest 文件里声明某个 activity 的时候制定了开启硬件加速的时候,该 activity 的绘制便会使用硬件加速,其对应的便是 ViewRootImpl 的硬件加速开启。ViewRootImpl 的硬件加速如果开启的话,会在进行 view 树根节点的绘制的时候,采用硬件绘制的方式进行。