View框架

View框架

Activity、WindowManagerGlobal、WMS等关系图

View树创建过程

ViewTree建立流程图

  1. ActivityThread负责处理各种核心事件,如“AMS通知App启动一个Activity”,将转化为其管理的消息、并调用对应的处理方法
  2. performLaunchActivity主要任务是生成一个Activity对象,并调用它的attach方法,然后间接调用它的onCreate方法
  3. attach方法为Activity内部变量赋值,其中最重要就是mWindow(PhoneWindow对象),每个Activity有且仅有一个Window实例
  4. PhoneWindow的setContentView方法生成DecorView(继承FrameLayout)和mContentParent(ViewGroup对象,容纳页面内容)
  5. WindowManager继承自ViewManager,真正实现为WindowManagerImpl,它间接调用WindowManagerGlobal的addView,添加新的ViewRootImpl,并将DecorView记录到ViewRootImpl中

    向WMS注册窗口

    PhoneWindow是App端对于“窗口”的描述,WindowState则是WMS中对“窗口”的描述。 IWindowSession和IWindow都是匿名Binder Server,需要借助一定方式才能提供服务。

  6. ViewRootImpl构造方法中,利用WMS的openSession打开一条通道
  7. WindowManagerImpl继承自WindowManager,存储App内部用于窗口管理的事务,完全属于本地;IWindowManager是WMS在App进程中的本地代理
  8. 向WMS申请注册一个窗口,同时将IWindow对象作为参数传递给WMS

    ViewRootImpl基本工作方式

    ViewRootImpl将和WMS进行一系列的通信,主要的触发源有两种:

    • View树内部请求,比如某个子View需要更新UI,它通过invalidate或其他方式发起请求,然后该请求就沿着View树层层向上传递,最终到达ViewRootImpl
    • 外部状态更新,比如WMS回调ViewRootImpl通知界面大小改变等 无论内部还是外部请求,ViewRootImpl都会把对应消息入队、之后依次处理(ViewRootHandler)。 ViewRoot工作流程

      View树遍历(traversal)

      系统综合考量各个view“请求”的过程,当过程结束后,各个view就能得到系统的最终分配,包括view的大小、位置以及自身显示内容(UI显示三要素)。

      遍历时机

    • Activity第一次显示:ViewRootImpl的setView中调用requestLayout触发第一次遍历请求
    • 外部事件,比如用户产生触摸事件
    • 内部事件:
    • View.requestLayout
    • View.setLayoutParams
    • View.invalidate

遍历流程的入口为scheduleTraversals方法,其中调用Choreographer的postCallback,一旦VSYNC信号到来,mTraversalRunnable被回调,进而调用doTraversal方法,进一步调用performTraversals方法。 ViewTree遍历时机

遍历流程

遍历主体是performTraversals方法,它的整体逻辑按照3个步骤进行:

  1. performMeasure,用于计算View在界面上的绘制区域大小(width、height)
  2. performLayout,用于计算View在界面上的绘制位置(left、top)
  3. performDraw,View绘制显示内容(canvas、paint)

    View和ViewGroup

    View属性:

    • id
    • tag
    • size
    • position
    • padding
    • visibility
    • background ViewGroup属性:
    • margin
    • layout

public class View implements Drawable.Callback, KeyEvent.Callback,  
        AccessibilityEventSource

Drawable表达了希望在屏幕上绘制的图像,还封装了相关的操作函数,当图像有变化或需要重绘时,通过Callback接口通知View。

Canvas

与Surface协作:

动画的本质是时间和图像的关系。根据视觉原理,人体对于一张图的”存储时间“是0.34秒,只要以特定速率来切换图片,人眼就会感觉整个画面是流畅的、没有卡顿现象。