1. 概述
Window是一个抽象类,具体实现是PhoneWindow,通过WindowManager创建。Window的具体实现位于WMS中,WindowManager和WMS是IPC交互过程。
通过mWindowManager.addView(view, layoutParams);添加一个Window。
Window有三种类型,应用Window(对应Activity),子Window(附属在特定父Window中)和系统Window,z-order层级大的会覆盖在层级小的Window上面。
应用Window的层级范围是1-99,子Window的范围是1000-1999,系统Window的范围是2000-2999。
2. Window内部机制
每一个Window都对应着一个View和一个ViewRootImpl,WindowManger由WindowMangerGlobal实现,内含mViews, mRoots, mParams;
root.setView会通过requestLayout来完成异步刷新请求,内部调用了scheduleTraversals(),然后调用performTraversals,之后依次调用performMeasure,performLayout和performDwaw。
IWindowSession.addToDisplay(IWindow),将Window添加到WMS中,在WMS中会为每个应用保留一个单独的Session。
WindowManager中提供removeView和removeViewImmediate,分别表示异步删除和同步删除。
真正删除View的逻辑在dispatchDetachedFromWindow内部实现:
1)垃圾回收相关工作,比如清除数据和消息、移除回调;
2)通过Session的remove删除Window,最终会调用WMS的removeWindow;
3)调用View的onDetachedFromWindow方法,在其中回收资源、终止动画和停止线程等;
4)在WindowManager中的mRoots,mParams,mDyingViews删除当前View;
3. Window的创建过程
1)在ActivityThread中performLaunchActivity中,通过类加载器创建Activity实例,创建Context,然后调用attach方法;
2)attach中创建Window,设置回调;
3)Window的setContentView方法:创建DecorView,将Activity的布局添加到DecorView中,回调Activity的onContentChanged方法;
4)在handleResumeActivity中会调用Activity的onResume方法,会调用WindowManager的addView方法,将DecorView添加到Window中。
5)在Dialog的构造函数中,会创建Window,设置回调,之后调用setContentView;在show方法中,调用WindowManager的addView方法。创建普通Dialog需要Activity的token,系统Dialog不需要,但要申请权限;
6)Toast也是基于Window实现的,但是Toast具有定时取消功能,所以含有Handler;Toast内部有Toast访问NotificationManagerService和NotificationManagerService回调Toast里的TN接口两类IPC过程;
7)Toast的show方法:调用NMS.enqueueToast(packageName, TN, duration),在NMS中排队完成后会通过TN.show显示,需要从Binder线程切回UI线程;TN.show方法中调用wms的addView。
8)PopupWindow、菜单栏以及状态栏都是通过Window来实现的。