public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
final WindowManagerPolicy mPolicy;
final ArraySet<Session> mSessions = new ArraySet<>();
final WindowHashMap mWindowMap = new WindowHashMap();
final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>();
final H mH = new H();
final WindowAnimator mAnimator;
final InputManagerService mInputManager;
final IActivityManager mActivityManager;
}
由Android进程的启动过程知道,程序会同过JNI调用ZygiteInit.main()进入Java层,在main()方法中完成启动工作,其中重要的一步就是调用startSystemServer()启动系统服务,WMS就是其中一个系统服务,startSystemServer()使用反射最终调用SystemServer.main()方法(本文源码参照Android P),
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
mSystemServiceManager = new SystemServiceManager(mSystemContext);
startBootstrapServices();
startCoreServices();
startOtherServices();
}
在main方法中直接调用SystemService的run(),在run中首先创建SystemServiceManager对象,然后利用SystemServiceManager分别启动引导服务、核心服务、其他服务,WMS的启动就在startOtherServices()过程中;
inputManager = new InputManagerService(context);
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
false, DUMP_FLAG_PRIORITY_CRITICAL);
在startOtherServices()中首先创建InputManagerService对象,然后调用WindowManagerService.main()创建WMS对象,此时最后一个参数就是前面讲的窗口策略类PhoneWindowManager,最后调用ServiceManager.addService()将WMS和InputManagerService保存在ServiceManager中;
public class WindowManagerService extends IWindowManager.Stub{
public static WindowManagerService main(final Context context, final InputManagerService im,
final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
WindowManagerPolicy policy) {
DisplayThread.getHandler().runWithScissors(() ->
sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
onlyCore, policy), 0);
return sInstance;
}
}
从上面代码中看出WindowManagerService是IWindowManager接口的代理类,在main()方法中调用DisplayThread.getHandler().runWithScissors()方法执行WindowManagerService的创建;
DisplayThread.getHandler().runWithScissors()其实就是发送一个事件消息,DisplayThread继承ServiceThread,而ServiceThread继承与HandlerThread,熟悉HandlerThread的同学都知道它是Android内部封装好的工具类,DisplayThread.getHandler()就是利用HandlerThread内部创建的Looper而创建的Handler,所以本质上执行的是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()中接收到事件runnable后,先判断当前线程是否为创建Looper的线程,如果是则直接在当前线程执行,否则创建BlockingRunnable封装事件并发送到创建线程的队列中,由上面的启动知道此时程序执行在systemserver线程,所以此处会创建BlockingRunnable对象
private static final class BlockingRunnable implements Runnable {
883 private final Runnable mTask;
884 private boolean mDone;
886 public BlockingRunnable(Runnable task) {
887 mTask = task;
888 }
889
890 @Override
891 public void run() {
892 try {
893 mTask.run();
894 } finally {
895 synchronized (this) {
896 mDone = true;
897 notifyAll();
898 }
899 }
900 }
901
902 public boolean postAndWait(Handler handler, long timeout) {
903 if (!handler.post(this)) {
904 return false;
905 }
906
907 synchronized (this) {
908 if (timeout > 0) {
909 final long expirationTime = SystemClock.uptimeMillis() + timeout;
910 while (!mDone) {
911 long delay = expirationTime - SystemClock.uptimeMillis();
912 if (delay <= 0) {
913 return false; // timeout
914 }
915 try {
916 wait(delay);
917 } catch (InterruptedException ex) {
918 }
919 }
920 } else {
921 while (!mDone) {
922 try {
923 wait();
924 } catch (InterruptedException ex) {
925 }
926 }
927 }
928 }
929 return true;
930 }
931 }
BlockingRunnable是Handler的内部类,是专门用来处理线程安全的类,在postAndWait中首先使用Handler发送事件到当前队列,然后调用wait()方法使当前线程进入等待,然后在run()中执行传入的事件,在事件执行结束后调用notifyAll()方法唤醒线程,结合这里的启动过程总结一下:
private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
WindowManagerPolicy policy) {
mAnimator = new WindowAnimator(this);
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mActivityManager = ActivityManager.getService();
}
在搞清楚上面的线程和执行的顺序后,下面进入到WMS的创建过程中,在WindowManagerService的构造函数中完成了WindowAnimator、mDisplayManager、mActivityManager的初始化,到此WMS启动已经完成
对与Window添加过程的前半部分见Android进阶知识树—— 理解WindowManager,本文只分析WMS执行的部分,上一文章中知道添加过程最终调用到WMS中的addWindow(),下面分步骤阅读源码;
public int addWindow(){
int res = mPolicy.checkAddPermission(attrs, appOp);//1
final DisplayContent displayContent = getDisplayContentOrCreate(displayId);//2
if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
parentWindow = windowForClientLocked(null, attrs.token, false);
if (parentWindow == null) {
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
&& parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
}
}
在addWindow()中具体执行如下:
WindowToken token = displayContent.getWindowToken(
1191 hasParent ? parentWindow.mAttrs.token : attrs.token);//1
final int rootType = hasParent ? parentWindow.mAttrs.type : type;
token = new WindowToken(this, binder, type, false, displayContent,
1247 session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);//2
atoken = token.asAppWindowToken();
总结:
final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid,
session.mCanAddInternalSystemWindow);// 1
mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);//2
res = mPolicy.prepareAddWindowLw(win, attrs);//3
mWindowMap.put(client.asBinder(), win);//4
win.mToken.addWindow(win);//5
addWindow()最后部分执行以下步骤:
关于Window的删除过程见Android进阶知识树—— 理解WindowManager,程序最终调用WMS的removeWindow(),在removeWindow()中首先获取到保存Window所有信息的WidowState对象,然后调用WindowState.removeIfPossible()方法,removeIfPossible中直接调用重载的方法,最终调用 removeImmediately();
void removeWindow(Session session, IWindow client) {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return;
}
win.removeIfPos();
}
}
@Override
void removeImmediately() {
super.removeImmediately();
mPolicy.removeWindowLw(this);
1921 disposeInputChannel();
1923 mWinAnimator.destroyDeferredSurfaceLocked();
1924 mWinAnimator.destroySurfaceLocked();
1925 mSession.windowRemovedLocked();
1927 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
1933 mService.postWindowRemoveCleanupLocked(this);
}
removeImmediately中主要做一些清理工作,移除当前Widow、通知当前窗口动画、移除mSession等;
到此这对WMS的介绍和窗口的添加就介绍完毕了,希望有所帮助,后面会继续整理相关内容!