WindowManagerService简称WMS,WMS是属于Android系统的其他服务,但是它的重要性和AMS在同一级别,作为“窗口管理员”,它负责窗口的创建、调度、显示以及触摸事件分发。也是一个Android程序猿必须了解的系统服务。
以一个《深入理解Android内核设计思想》中的比方开始:
整个界面就像由N个演员参与的话剧:SurfaceFlinger是摄像机,WMS是导演,ViewRoot就是演员个体。摄像机(SurfaceFlinger)的作用是单一而规范的——它负责客观地捕抓当前的画面,然后真实地呈现给观众;导演(WMS)则会考虑到话剧的舞台效果和视觉美感,如他需要根据实际情况来安排各个演员的排序站位,谁在前在后,都会影响演出的“画面效果”与“剧情编排;而各个演员的长相和表情(ViewRoot),则更多地取决于他们自身的条件与努力。正式通过这三者的“各司其职”,才能最终为观众呈现出一场美妙绝伦的“视觉盛宴”。
SyetemServer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| private void startOtherServices() { WindowManagerService wm = null; traceBeginAndSlog("StartInputManagerService"); inputManager = new InputManagerService(context); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartWindowManagerService"); wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); inputManager.start(); wm.displayReady(); wm.systemReady(); }
|
这些是涉及到WMS的相关代码,可以看到,InputManagerService作为参数传递给了WMS,而WMS又作为参数传给了AMS。
WMS.main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static WindowManagerService main(final Context context, final InputManagerService im, final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore) { final WindowManagerService[] holder = new WindowManagerService[1]; DisplayThread.getHandler().runWithScissors(new Runnable() { @Override public void run() { holder[0] = new WindowManagerService(context, im, haveInputMethods, showBootMsgs, onlyCore); } }, 0); return holder[0]; }
|
WindowManagerService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { mContext = context; mHaveInputMethods = haveInputMethods; mAllowBootMessages = showBootMsgs; mOnlyCore = onlyCore; ...... mInputManager = inputManager; mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); mDisplaySettings.readSettingsLocked();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplays = mDisplayManager.getDisplays(); for (Display display : mDisplays) { createDisplayContentLocked(display); }
mActivityManager = ActivityManagerNative.getDefault();
mAnimator = new WindowAnimator(this); mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
LocalServices.addService(WindowManagerInternal.class, new LocalService()); initPolicy();
Watchdog.getInstance().addMonitor(this); ......
}
|
initPolicy
1 2 3 4 5 6 7 8 9 10 11
| private void initPolicy() { UiThread.getHandler().runWithScissors(new Runnable() { @Override public void run() { WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this); } }, 0); }
|
在initPolicy中,mPolicy实际为PhoneWindowManager。
final WindowManagerPolicy mPolicy = new PhoneWindowManager();
“system_server”线程中会调用WMS的main方法,main方法中会创建WMS,创建WMS的过程运行在”android.display”线程中,它的优先级更高一些,因此要等创建WMS完毕后才会唤醒处于等待状态的”system_server”线程。
WMS初始化时会执行initPolicy方法,initPolicy方法会调用PWM的init方法,这个init方法运行在”android.ui”线程,并且优先级更高,因此要先执行完PWM的init方法后,才会唤醒处于等待状态的”android.display”线程。
图片来自gityuan博客