(十二)Window和WindowManager的使用解析

来源:互联网 发布:知乎 最尴尬的吹牛 编辑:程序博客网 时间:2024/05/17 12:50
       Window是一个抽象类,具体实现是PhoneWindow,具体实现位于WindowManagerService中。WindowManager和WindowManagerService的交互是一个IPC的过程。
      WindowManager的LayoutParams有两个参数很重要,Flags,表示Window的属性,Type,表示Window的类型。
      Window有三种类型,分别为应用Window(1~99)、子Window(1000~1999)和系统Window(2000~2999)。
      WinsowManager提供的方法有三个addView()、updateViewLayout()和removeView()。这三个方法定义在ViewManager中,WindowManager继承了ViewManager。

Activity和Dialog的window的创建过程
       1,在Activity的attach方法中,系统会创建Activity所属的Window对象并为其设置回调接口,通过PolicyManager的makeNewWindow方法实现,(PolicyManager实现了IPolicy策略接口,但PolicyManager真正的实现是在Policy类),Policy累中的makeNewWindow方法中返回new PhoneWindow(),(可以看出Window的实现类是PhoneWindow),到此window已经创建完成,
       2,下一步关联到Activity上,查看Activity的setContentView方法,可知Activity将具体实现交给Window处理(getWindow.setContentView()),查看PhoneWindow的setContentView方法
       3,分几步 a,如果没有DecorView,就创建它(installDecor方法),是一个空白的Framelayout  
                        b,将View添加到DecorView的mContentParent中
                       c,回调Activity的onContentChange方法通知Activity视图已经改变
       4,到此Window已经被创建但DecorView未被WM识别,在ActivtyThread的handleResumeActivity方法里调用Activity的OnResume方法,接着调用makeVisible方法(在此方法中调用WM的addView方法并显示)。

Toast的工作原理:
      因其有定时取消功能,所以系统采用handle,在其内部有两类IPC过程,一类是Toast访问NotificationManagerService,第二类是NMS回调Toast里的TN接口。Toast的show方法和cancel方法内部是IPC过程,具体实现是
   show方法中得到TN对象(Binder对象) ,获得NMS服务,得到应用包名,调用NMS的enqueueToast方法(参数:包名,mTn,时长),在enqueueToast方法离吧Toast请求封装成ToastRecoord对象并将它添加到一个mToastQueue队列中(本质是ArrayList集合,大小50),之后NMS通过showNextTaostLocked方法显示当前Toast。Toast的显示是由ToastRecord的callback的show方法完成的,callback实际是TN对象的远程Binder。
   cancel方法中调用mTN的hide方法,调用NMS的cancelToast方法(参数包名,mTN)。与显示一样。

因为TN(ToastRecord)运行在远程进程中,所以内部使用了handler,post了两个Runnable对象,其内部调用TN的handleShow(内部得到WM,调用addView方法)和handleHide(内部调用removeView方法)方法。



Window的添加过程:
      WindowManager是一个接口,真正实现是WindowManagerImpl类,但WindowManagerImpl类也没直接实现,而是全部交给WindowMnagerGlobal来处理,在WindowMnagerGlobal的addView方法中分为几步:对view、 display,params等属性参数进行检验,若是子View,还需调整布局参数。
      在addView方法中如下:

       其中比较重要的是一些集合列表,如下所示,

     之后通过ViewRootImpl对象root调用setViw方法来更新界面完成Window的添加(见上图), 该过程通过requestLayout来完成异步刷新请求。
setView方法中

如下为requestLayout方法:


Window的删除过程
     Window的删除过程和添加过程一样,先通过WindowManagerImpl后,再进一步通过WindowManagerGlobal来实现。
     WindowManagerGlobeal的removeView方法:

  
  调用removeViewLocked来做进一步删除



     而在ViewRootImpl的die方法中,之后进行上述方法中添加要删除的View到集合列表中。


在dispatchDetachFromWindow方法中主要做的内容:
   1.垃圾回收 ,如清除数据和消息,移除回调等  
   2.通过Session的remove方法删除Window,最终调用mService的removeWindow方法,同添加一样
   3.调用View的dispatchDetachFromWindow方法,在内部会调用View的onDetachedFromWindow()以及onDetachedFromWindowInternal()。当View从Window移除时,onDetachedFromWindow工作。
   4.调用WindowManagerGlobal的doRemoveView方法刷新数据,包括mRoots、mParams、mDyingViews,需要将当前Window所关联的这三类对象从列表删除。

Window的更新过程
     在WindowMnagerGlobal的updateViewLayout方法 




原创粉丝点击