Android开发艺术探索 第八章

理解WIndow和WIndowManager

WIndow表示一个窗口的概念,Android中所有的视图都是通过WIndow来呈现。

8.1WIndow和WIndowManager

为了分析WIndow的工作机制,可以看一下windowManager里面的addView方法,可以关注一下LayoutParams中的参数,比如其中的flag和type两个参数,具体可以参考最新的API,书中的只是针对某个版本的,最新一些变量已经修改。

flag 表示Window的属性,主要控制窗口的显示特性,显示层级。

type 表示Window的类型,分别有三种,应用Window、子Window和系统Window。

好理解一点应用的Window对应activity,Dialog就是子窗口,系统的就是TOAST这种。

Window事分层的,每个Window都有对应的z-ordered,层级大的会覆盖在层级小的,前面三种分别对应的范围可以留意一下:应用窗口范围是1-99,子窗口事1000~1999,系统的是2000~2999,这符合整体的设计逻辑,有需要的在最上面。

8.2 Window的内部机制

Window 是一个抽象的概念,每个Window都对应着一个View和ViewRootImpl,Window和View是通过ViewRootImpl来建立联系的,因此Window不是实际存在的,它是以View的形式存在,一般也是通过WindowManager来访问Window。

8.2.1 Window的添加过程

Window的添加是通过WindowManager的addView来实现的,WindowManager是一个接口,还有updateViewLayou()t、removeView()

WindowManager里面的addView是由WindowManagerGlobal来实现的,这是典型的桥接模式。主要方法分为如下几 步:

1.检查参数是否合法,如果是子Window那么还需要调整一些布局参数

2.创建ViewRootImpl并将View添加到列表中

3.通过ViewRootImpl来更新界面并完成Window的添加过程

WindowSession来完成最终的Window添加,它其实是一个binder对象,真正的实现类是Session,Window添加过程就是一次IPC调用。Session内部通过WindowManagerService来实现Window的添加,也就是我们平时说的WMS,需要专研这一块的和研究相关源码。

8.2.2 Window的删除过程

Window的删除过程其实和添加过程一样,需要留意删除是分同步和异步删除的,需要确定调用的方式。可以看依稀真正删除方法里面的内部实现,主要做了四件事:

1.垃圾回收相关工作,比如清除数据和消息,移除回调

2.通过IPC过程调用WMS的removeWindow方法

3.资源回收的工作,比如终止动画,停止线程等

4.删除Window所关联过的对象,比如mRoots,mParams等

8.2.3 Window的更新过程

还是分析WindowManagerGlobal里面的updateViewLayout方法,具体如下

1.更新View的LayoutParams,接着在更新viewRootImpl中的LayoutParams,这些都是通过setLayoutParams方法实现的

2.调用scheduleTraversals方法来对View重新布局,包括测量、布局、重绘着三个过程。

3.通过IPC调用WMS来更新Window的视图。

8.3 Window的创建过程

View必须附在Window这个抽象的概念上,所有由视图的地方必然2由Window存在。

8.3.1 activity的Window创建过程

在activity的attach方法里面,系统会创建activity所属的Window对象并为其设置回调接口,Window对象的创造是通过PolicyManager的makeNewWindow方法实现的,由于activity实现的Window的callback接口,因此当Window接受外界的状态改变就会回调activity的方法。

Window的具体实现是PhoneWindow,关于这里面有兴趣的可以看一下systemUI相关代码。

关注一下setContentView方法,具体实现最终也是在PhoneWindow里面,可以记一下相关逻辑即可:

1.如果没有DoctorView,那么就创建它。

2.将View添加到DoctorView的mContentParent中

3.回调activity的oncontectChanged方法通知视图已经发生改变

8.3.2 Dialog的Window创建过程

Dialog的Window创建和activity的基本类似

1.创建Window,同样是PolicyManager里面的makeNewWindow,后续流程和活动基本一样。

2.需要留意上下文对象不太一样,需要使用activity的context,因为这个里面才有应用的token,前面说过系统层级,对话框的层级需要指定活动。

8.3.3 Toast的Window创建过程

toast的创建和Dialog不同,toast具有定时取消功能,所以系统采用了handler,在toast内部有两类IPC过程,一个是方法Toast访问NMS,第二类是NMS回调Toast里面的TN接口。

Toast属于系统Window,它的内部视图由系统默认样式或者自定义View,不管那种方式,基本都是调用显示和隐藏的过程。

显示和隐藏都是通过NMS来实现的,因此都是通过远程调用的方式,TN这个类,他是一个binder类,所以需要handler将其切换到当前线程中,意味在没有Looper的线程中弹出,这一点需要留意,也就是次线程一般都没办法直接调用。

看一下show的过程,NMS中会封装相关请求,参数有包名、回调、时长,封装到mToastQueue里面,最多存在50个,防止DOS攻击。正常情况下一个应用都用不到上限。添加到列表后,就会通过showNextToastLocked方法来显示当前的Toast,Toast的显示是由callback来完成的,实际是Toast中TN对象的远程binder,最终调用Toast请求的应用的binder线程中。

Toast显示后,会通过scheduleTimeoutLocked来发送一个延迟消息,具体分为长时间3.5S,短时间2s,延迟时间到达后,NMS会通过cancelToastLocked方法来隐藏Toast并从队列中移除,如果队列中还有其他Toast,那么会继续显示其他Toast。

具体实现流程可以看到其实还是WindowManager里面的addView和removeView实现,只不过层层封装,通过IPC调用系统里面的服务。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代我西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值