快短小介绍WindowManagerService的启动流程。
WMS的启动流程
在系统启动流程中,Zygote
进程通过fork
自己来创建SystemServer
进程。SystemServer
进程的主要职责之一就是创建SystemServiceManger
,使自己成为服务的注册中心,并启动三种不同类型的服务:引导服务、核心服务、其他服务。
WMS被划分到其他服务。我们以SystemServer
的main
函数为入口来分析WMS的启动流程。
1、SystemServer.main
public static void main(String[] args) {
new SystemServer().run();
}
2、SystemServer.run
如下所见,SystemServer
先加载android_servers
动态库,创建SystemServiceManager
对象,将服务划分为三种类型的服务引导服务、核心服务、其他服务。
private void run() {
// 初始化本地服务
System.loadLibrary("android_servers");
...
//创建系统服务管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
//启动三种类型的服务
try {
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
...
} finally {
...
}
}
3、SystemServer.startOtherServices
startOtherServices
函数会创建非常多的服务,这里重点关注WMS
的创建,先创建了InputManagerService
,再调用WindowManagerService
的main
函数。
...
inputManager = new InputManagerService(context);
...
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
...
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
...
//初始化PhoneWindowManager和添加WatchDog监听
wm.onInitReady();
...
wm.displayReady();
...
wm.systemReady();
4、WindowManagerService.main
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
Supplier<Surface> surfaceFactory,
Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
atm, transactionFactory, surfaceFactory, surfaceControlFactory), 0);
return sInstance;
}
DisplayThread
继承自ServiceThread
类,ServiceThread
又继承自HandlerThread
类。是一个前台系统共享的单例线程,主要服务于WindowManager
、DisplayManager
、InputManager
快速实时执行显示相关的操作。
5、Handler.runWithScissors
public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
if (r == null) {
throw new IllegalArgumentException("runnable must not be null");
}
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be non-negative");
}
if (Looper.myLooper() == mLooper) {
r.run();
return true;
}
BlockingRunnable br = new BlockingRunnable(r);
return br.postAndWait(this, timeout);
}
当前代码是运行在SystemServer
的主线程,runWithScissors
函数使得Runable
对象的run函数切换到DisplayThread
代码执行。创建了BlockingRunnable
类型的对象r,并调用其他postAndWait
函数。此时参数timeout
是0,this是自身Handler
对象。
6、BlockingRunnable.postAndWait
//BlockingRunnable的postAndWait函数
public boolean postAndWait(Handler handler, long timeout) {
if (!handler.post(this)) {//1
return false;
}
synchronized (this) {
if (timeout > 0) {
while (!mDone) {
...
try {
wait(delay);
} catch (InterruptedException ex) {
}
}
} else {
while (!mDone) { //2
try {
wait(); //3
} catch (InterruptedException ex) {
}
}
}
}
return true;
}
//BlockingRunnable的run函数,mTask是构造函数传递进来的Runable对象
public void run() {
try {
mTask.run(); //4
} finally {
synchronized (this) {
mDone = true; //5
notifyAll();
}
}
}
注释1,由于handler
对象来自DisplayThread
线程,所以BlockingRunnable
的run
函数会在DisplayThread
线程中执行。DisplayThread
线程在执行注释4后,会执行注释5,将mDone
设置为true,然后通知其他等待的线程继续执行。
注意到此时还运行在SystemServer
线程中,当注释1的Runable
对象添加到DisplayThread
线程的Handler
的消息队列会立即返回true
,继续执行注释1后续代码。而不是等待DisplayThread
线程执行完BlockingRunnable
对象的run
函数再返回。mDone
变量默认false
,执行到注释3代码时,如果mDone
为true
,SystemServer
线程则不进入等待状态,代表DisplayThread
已经执行完run
函数,否则进入等待状态,直到DisplayThread
线程执行完run
函数通知SystemThread
线程醒来继续执行。
总的来说就是,SystemServer
线程会等待DisplayThread
线程创建好WMS
之后,再继续执行后续内容。到这里WindowMangerService
对象也创建完毕。