WindowManagerService 就是位于 Framework 层的窗口管理服务,它的职责就是管理系统中的所有窗口。
Android中的窗口概念:屏幕上一块用于绘制各种UI元素并可以响应用户输入的一块矩形区域。从原理上来看,窗口的概念是独自占有一个Surface实例的显示区域。如Dialog、Activity的界面、壁纸、状态栏以及Toast等都是窗口。
WindowManagerService 添加一个窗口的过程,其实就是 WindowManagerService 为其分配一块 Surface 的过程,一块块的 Surface 在 WindowManagerService 的管理下有序的排列在屏幕上,Android 才得以呈现出多姿多彩的界面。
启动流程:
WindowManagerService由SystemServer.java启动,zygote进程会调用SyetemServer.java中的run方法开启相关服务。
SystemServer.java
frameworks/base/services/java/com/android/server/SystemServer.java
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); }
1、SystemServer的run方法
private void run() { try { ... // Initialize the system context. createSystemContext(); // 创建,启动SystemService和管理SystemService的生命周期 mSystemServiceManager = new SystemServiceManager(mSystemContext); // 添加到本地服务的全局注册表中。 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // Start services. try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices(); //开启引导服务 startCoreServices(); //开启核心服务 startOtherServices(); //开启其他服务 } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } ... }
WindowManagerService在startOtherServices()方法中被启动,下面看startOtherServices()方法:
2、SystemServer的startOtherServices方法
private void startOtherServices() {
......
WindowManagerService wm = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
......
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm); //注册服务
......
mActivityManagerService.setWindowManager(wm); //和ActivityManagerService进行关联
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
......
try {
wm.displayReady(); //初始化显示信息,尺寸,位置等
} catch (Throwable e) {
reportWtf("making display ready", e);
}
......
try {
wm.systemReady(); //通知WMS系统的初始化工作已完成
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
......
}
可以看到SystemServer启动WindowManagerService是调用WindowManagerService的main方法,WMS的main方法是运行在SystemServer的run方法中,换句话说就是运行在”system_server”线程中。下面进一步分析启动流程中涉及的主要方法。
二、WindowManagerService
1、WindowManagerService的main方法
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];
}
DisplayThread extends ServiceThread,其中ServiceThread extends HandlerThread, 该Handler运行在名为”android.display”的线程中,这个runWithScissor方法是一个阻塞方法,会阻塞到直到WindowManagerService创建成功。由于WMS的main方法运行在SystemServer线程中(”system_server”线程),所以“system_server“线程会处于等待状态,等到“android.display“执行完毕,下面看下runWithScissor的代码逻辑。
2、Handler的runWithScissors()
public final boolean runWithScissors(final Runnable r, long timeout) {
......
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
runWithScissors同步运行指定的任务,如果当前线程与处理的线程相同,则立即运行,否则通过handler.post()方式执行。可以看出postAndWait(this, timeout)方法中是阻塞方法,直到任务执行完成,代码如下:
public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {
return false;
}
synchronized (this) {
if (timeout > 0) {
final long expirationTime = SystemClock.uptimeMillis() + timeout;
while (!mDone) {
long delay = expirationTime - SystemClock.uptimeMillis();
if (delay <= 0) {
return false; // timeout
}
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) {
try {
wait();
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
至此,WindowManagerService已经创建完毕,下面看下WMS构造器中主要的初始化工作。
3、WindowManagerService构造方法
private WindowManagerService(Context context, InputManagerService inputManager, boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { mHaveInputMethods = haveInputMethods; ...... mInputManager = inputManager; // Must be before createDisplayContentLocked. mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); mDisplaySettings = new DisplaySettings(); //关于display的设置 mDisplaySettings.readSettingsLocked(); //读取/data目录下的display_settings.xml文件 mWallpaperControllerLocked = new WallpaperController(this);//控制壁纸窗口的可视性,排序等 mWindowPlacerLocked = new WindowSurfacePlacer(this); //定位窗口以及surface的位置 mLayersController = new WindowLayersController(this); //用于将图层分配给显示器上的窗口的控制器。 LocalServices.addService(WindowManagerPolicy.class, mPolicy); //窗体策略 mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));//接收输入事件 mFxSession = new SurfaceSession();//和surfaceflinger连接,创建管理surface实例 mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); //管理显示属性 mDisplays = mDisplayManager.getDisplays(); for (Display display : mDisplays) { createDisplayContentLocked(display); //创建对应的DisplayContent对象,DisplayContent描写叙述了一块能够绘制窗体的屏幕。 } mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); //键盘锁禁用 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);//电源管理本地服务器接口 mPowerManagerInternal.registerLowPowerModeObserver( //监听低电 new PowerManagerInternal.LowPowerModeListener() { @Override public void onLowPowerModeChanged(boolean enabled) { synchronized (mWindowMap) { if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) { mAnimationsDisabled = enabled; dispatchNewAnimatorScaleLocked(null); } } } }); mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled(); mScreenFrozenLock = mPowerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); mScreenFrozenLock.setReferenceCounted(false); mAppTransition = new AppTransition(context, this); //过渡动画 mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); mBoundsAnimationController = new BoundsAnimationController(mAppTransition, UiThread.getHandler()); mActivityManager = ActivityManagerNative.getDefault(); mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); //应用程序操作的跟踪 AppOpsManager.OnOpChangedInternalListener opListener = new AppOpsManager.OnOpChangedInternalListener() { @Override public void onOpChanged(int op, String packageName) { updateAppOpsState(); } }; mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null, opListener); mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener); mContext.registerReceiver(mBroadcastReceiver, filter); mSettingsObserver = new SettingsObserver(); //监听设置内容的变更 //唤醒锁,SCREEN_BRIGHT_WAKE_LOCK屏幕高亮显示,保持CPU运转,ON_AFTER_RELEASE保持屏幕亮一段时间,直到默认超时后黑屏 mHoldingScreenWakeLock = mPowerManager.newWakeLock( PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM); mHoldingScreenWakeLock.setReferenceCounted(false); //代表WindowManagerService在单独任务中执行动画和Surface操作的Singleton类。 mAnimator = new WindowAnimator(this); mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); LocalServices.addService(WindowManagerInternal.class, new LocalService()); initPolicy(); //WindowManagerPolicy初始化,主要职责是负责UI。实现类PhoneWindowManager // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); ......... }