Window 和 WindowManager

这篇文章是本着抛砖引玉的目的,如果有不严谨,甚至错误地方,劳驾各位指正。

有一群很(hua)好(qian)学(mai)的粉丝问,Window和WindowManager是什么东西,我就去查资料了。

说到这得吐槽一下。

一开始,我只想知道window是什么东西,每!一!篇!文章都说,window是一个抽象的东西,抽象的东西...然后就没有了。抽象xxx啊抽象!难道哪天面试官问我,window是什么?我就回答说,window是个很抽象的东西?

并且,那些文章都无一例外的又臭又长,没看一会儿就不由得生出一种,“这孙子在说什么?”,的感觉。

OK,说正事。

首先,谈谈Window到底是啥。它是一个很抽象的东西。

拿明星来举例子:
有的明星是单独发展的,比如周杰伦,如果我们碰到他会怎么喊他呢,直接喊“周杰伦”对不对。
有的明星是以组合形式发展的,并且分工不同,比如五月天,他们有主唱、有键盘、有二胡、有三弦儿...如果碰到五月天我们会怎么喊呢,应该没人傻到会把几位成员的名字连起来挨个喊一遍吧?这时候,“五月天”是对多个人的总称

同理,window也是一个组合,成员分别是View和ViewRootImpl。View是颜值担当,是给大家看的。ViewRootImpl是劳动担当,是干活的,比如更新View。(这样理解不知是否严谨)

概念弄明白后就看一下流程。

Window 和 WindowManager_第1张图片
调用流程

原谅我图画的很糙。

  • 竖直方向是类的继承关系,水平方向是方法的调用流程。被框起来的是各个类里面的方法。相信通过方法名也能看得出怎么调用的吧。
  • ViewManager中定义了常用的三个方法,addView、updateViewLayout、removeView,即添加View、更新View和删除View
  • WindowManager是个接口,实现它是WindowManagerImpl。所以,图中WindowManagerImpl的三个方法是从ViewManager继承来的。
  • WindowManagerImpl和WindowManagerGlobal三个方法长得一模一样,这里使用的桥接模式,意思就是,分配给WindowManagerImpl干的工作,被它原封不动的转给勤劳的WindowManagerGlobal对象干了。
  • ViewRootImpl,待会再说
  • IPC调用,说明WindowManagerService是运行在其他进程的

分情况分析一下调用流程,直接从WindowManagerGlobal开始:

  1. 添加View
    Window这个“组合”是在Global的addView方法里被创建的。
    addView过程中,会new一个ViewRootImpl对象和View“绑定”,用来操作View。并且,在Global对象中有专门的数据结构来存储View,和与之对应的ViewRootImpl和LayoutParams,以便以后可查。
    接下来,ViewRootImpl对象的addView会被调用,最后,通过它的一个成员变量,Session对象,完成对WindowManagerService中addView的跨进程调用。
    Session为什么有如此神通?
    因为Session实现了IWindowSession,而IWindowSession正是一个Binder对象。
  2. 删除View
    同理,跨进程调用还是通过Session。
    唯一需要说明的就是,ViewRootImpl里面有两个remove相关的方法:removeView和removeViewImmediate。
    两者区别是:
  • 前者是异步删除,方法内部只发送了一个MSG_DIE的消息就返回了,ViewRootImpl的handler会处理该消息并调用doDie方法
  • 后者是同步删除,方法不发消息,直接调用doDie方法
  1. 更新View
    没什么需要说的,从头到尾走下来就是。

你可能感兴趣的:(Window 和 WindowManager)