1.SystemServer:啟動(dòng)WindowManagerService
public static WindowManagerService main(final Context context,
final PowerManagerService pm, final DisplayManagerService dm,
final InputManagerService im, final Handler wmHandler,
final boolean haveInputMethods, final boolean showBootMsgs,
final boolean onlyCore) {
final WindowManagerService[] holder = new WindowManagerService[1];
wmHandler.runWithScissors(new Runnable() {
@Override
public void run() {
holder[0] = new WindowManagerService(context, pm, dm, im,
haveInputMethods, showBootMsgs, onlyCore);
}
}, 0);
return holder[0];
}
2.WindowManagerService的初始化
private WindowManagerService(Context context, PowerManagerService pm,
DisplayManagerService displayManager, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = showBootMsgs;
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
/* 得到InputManagerService抑淫。輸入事件最終要分發(fā)給具有焦點(diǎn)的窗口嗤堰,由WMS負(fù)責(zé)與IMS交互
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerService = displayManager;
mHeadless = displayManager.isHeadless();
mDisplaySettings = new DisplaySettings(context);
mDisplaySettings.readSettingsLocked();
mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
mFxSession = new SurfaceSession();
/* 初始化DisplayContent列表寻馏。DisplayContent是Android4.2為支持多屏幕輸出所引入的一個(gè)
概念婉称。一個(gè)DisplayContent指代一塊屏幕柒莉,屏幕可以是手機(jī)自身的屏幕祭隔,也可以是基于Wi-FiDisplay
技術(shù)的虛擬屏幕[3]*/
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
Display[] displays = mDisplayManager.getDisplays();
for (Display display : displays) {
createDisplayContentLocked(display);
}
mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
/* 電源管理模塊當(dāng)有關(guān)屏亮屏動(dòng)作的時(shí)候压储,需要WindowManagerPolicy去做相關(guān)的系統(tǒng)UI顯示動(dòng)作 */
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
mScreenFrozenLock.setReferenceCounted(false);
mAppTransition = new AppTransition(context, mH);
mActivityManager = ActivityManagerNative.getDefault();
mBatteryStats = BatteryStatsService.getService();
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
new AppOpsManager.OnOpChangedInternalListener() {
@Override
public void onOpChanged(int op, String packageName) {
updateAppOpsState();
}
}
);
// 初始化全局系統(tǒng)設(shè)置的窗口切換動(dòng)畫的值
mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
IntentFilter filter = new IntentFilter();
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction("jidou.app.action.AUTO_REBOOT");
mContext.registerReceiver(mBroadcastReceiver, filter);
mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ON_AFTER_RELEASE, TAG);
mHoldingScreenWakeLock.setReferenceCounted(false);
//管理窗口動(dòng)畫對(duì)象
mAnimator = new WindowAnimator(this);
//實(shí)例化WindowManagerPolicy,實(shí)際就是初始化PhoneWindowManager
initPolicy(UiThread.getHandler());
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
SurfaceControl.openTransaction();
try {
createWatermarkInTransaction();
mFocusedStackFrame = new FocusedStackFrame(
getDefaultDisplayContentLocked().getDisplay(), mFxSession);
} finally {
SurfaceControl.closeTransaction();
}
}
3.初始化PhoneWindowManager
①.WindowManagerService對(duì)象創(chuàng)建的時(shí)候會(huì)通過(guò)PolicyManager的靜態(tài)方法makeNewWindowManager()得到類型為IPolicy的mPolicy全局變量;
②.在PolicyManager類加載中德频,會(huì)通過(guò)反射的方式創(chuàng)建類型為IPolicy的 sPolicy對(duì)象苍息,
③ IPolicy是一個(gè)接口文件,具體實(shí)現(xiàn)在為framework/base/policy/src/com/android/internal/policy/impl/Policy.java類,所以最終PolicyManager.makeNewWindowManager() 調(diào)用的就是Policy中的makeNewWindowManager(),返回的是一個(gè)PhoneWindowManager對(duì)象竞思。
④ initPolicy方法所做的動(dòng)作就是執(zhí)行PhoneWindowManager中的init方法表谊,做一些對(duì)象初始化動(dòng)作,以及廣播的監(jiān)聽盖喷,配置參數(shù)讀取等爆办。
4.PhoneWindowManager初始化完成之后,繼續(xù)回來(lái)WindowManagerServivce中传蹈,相繼執(zhí)行displayReady()押逼,systemReady()兩個(gè)函數(shù),然后等待客戶端請(qǐng)求添加窗口惦界。
5.接下來(lái)開始添加系統(tǒng)窗口挑格,以添加NavigationBar為例,在SystemServer中沾歪,資源加載完成后漂彤,啟動(dòng)系統(tǒng)級(jí)應(yīng)用SystemUI
SystemUI中有眾多的組件,繼承自SystemUI.java抽象類灾搏,這里不再贅述挫望,我直接查找NavigationBar的創(chuàng)建流程。
①.SystemUIService在其生命周期的onCreate函數(shù)中狂窑,通過(guò)反射的方式媳板,創(chuàng)建SystemBars組件的對(duì)象,然后調(diào)用其start()方法
②.在SystemBars的start方法中泉哈,實(shí)例化ServiceMonitor蛉幸,并調(diào)用它的start()方法,最終會(huì)走到SystemBars中onNoService中丛晦,通過(guò)反射的方式奕纫,初始化父類為BaseStatusBar的PhoneStatusBar對(duì)象,然后執(zhí)行該對(duì)象的start()方法烫沙。
③.在PhoneStatusBar中匹层,添加NavigationBar的邏輯代碼片段
//配置NavigationBar視圖
private void prepareNavigationBarView() {
mNavigationBarView.reorient();
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
mNavigationBarView.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//.....
}
//設(shè)置NavigationBar的窗口信息
private WindowManager.LayoutParams getNavigationBarLayoutParams() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
0
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.setTitle("NavigationBar");
lp.windowAnimations = 0;
return lp;
}
private void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
if (mNavigationBarView.isAttachedToWindow()) return;
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
分析代碼可知,NavigationBar是一個(gè)類型為WindowManager.LayoutParams.TYPE_NAVIGATION_BAR的視圖窗口锌蓄,通過(guò)WindowManager添加到視圖系統(tǒng)中升筏。
④繼續(xù)走,mWindowManager是在BaseStatusBar中初始化的瘸爽,通過(guò)源碼跟蹤您访,我們發(fā)現(xiàn)得到的其實(shí)為WindowManagerImpl.java,
//在源碼core/java/android/app/ContextImpl.java中
registerService(WINDOW_SERVICE, new ServiceFetcher() {
Display mDefaultDisplay;
public Object getService(ContextImpl ctx) {
Display display = ctx.mDisplay;
if (display == null) {
if (mDefaultDisplay == null) {
DisplayManager dm = (DisplayManager)ctx.getOuterContext().
getSystemService(Context.DISPLAY_SERVICE);
mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
}
display = mDefaultDisplay;
}
return new WindowManagerImpl(display);
}});
所以mWindowManager.addView相當(dāng)于執(zhí)行了如下代碼。
public void addView(View view, ViewGroup.LayoutParams params) {
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
這里的mDisplay為默認(rèn)的蝶糯,mParentWindow對(duì)象為NULL洋只。
mGlobal為WindowManagerGlobal對(duì)象的實(shí)例,于是添加視圖走到了該類的addView方法中,代碼如下:
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
if (view == null) { //不允許添加空對(duì)象的視圖
throw new IllegalArgumentException("view must not be null");
}
if (display == null) {
throw new IllegalArgumentException("display must not be null");
}
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
if (parentWindow != null) { //添加NavigationBar時(shí)识虚,這里我們的parentWindow是為空
parentWindow.adjustLayoutParamsForSubWindow(wparams);
}
ViewRootImpl root;
View panelParentView = null;
synchronized (mLock) {
// Start watching for system property changes.
if (mSystemPropertyUpdater == null) {
mSystemPropertyUpdater = new Runnable() {
@Override public void run() {
synchronized (mLock) {
for (int i = mRoots.size() - 1; i >= 0; --i) {
mRoots.get(i).loadSystemProperties();
}
}
}
};
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
}
int index = findViewLocked(view, false);
if (index >= 0) {
if (mDyingViews.contains(view)) {
// Don't wait for MSG_DIE to make it's way through root's queue.
mRoots.get(index).doDie();
} else {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
// The previous removeView() had not completed executing. Now it has.
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
synchronized (mLock) {
final int index = findViewLocked(view, false);
if (index >= 0) {
removeViewLocked(index, true);
}
}
throw e;
}
}
⑤ 這里創(chuàng)建一個(gè)ViewRootImlp對(duì)象,然后調(diào)用了它的setView方法肢扯,傳遞三個(gè)參數(shù),一個(gè)正在添加的視圖view担锤,一個(gè)視圖的相關(guān)參數(shù)蔚晨,一個(gè)父類容器view,這里為空
⑥ 接著往下肛循,可以看到setView中铭腕,有這樣一句話
//.......
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}
//.......
⑦ mWindowSession.addToDisplay實(shí)際就是調(diào)用了Session.java中的addToDisplay,
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets,
InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outInputChannel);
}
最終addToDisplay被執(zhí)行到了WindowManagerService的addWindow函數(shù)中