WindowInsets流程:
setContentView过程可以分为两部分,一部分是构建DecorView布局,一部分是将布局添加到window中。主要看添加到window流程:ActivityThread.handleResumeActivity-WindowManager.addView-WIndowManagerImpl.addView-WindowManagerGloble.addView-ViewRootImpl.setView-.requestLayout-.scheduleTraversals-.TraversalRunnable-.doTraversal-.performTraversals-.dispatchApplyInsets(View host)-host.dispatchApplyWindowInsets(host其实就是PhoneWindow中的DecorView),说明一下,performTranversals方法依次执行dispatchApplyInsets、performMeasure、performLayout和performDraw,最终完成View的绘制流程.
接下来就是View和ViewGroup层次的WindowInsets调用流程了,由上面可知最后调用DecorView.dispatchApplyWindowInsets,而它直接调用ViewGroup的dispatchApplyWindowInsets,因为DecorView、FrameLayout都没有重写dispatchApplyWindowInsets方法
@Override public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { insets = super.dispatchApplyWindowInsets(insets); if (!insets.isConsumed()) { final int count = getChildCount(); for (int i = 0; i < count; i++) { insets = getChildAt(i).dispatchApplyWindowInsets(insets); if (insets.isConsumed()) { break; } } } return insets; }
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { try { //将PLAGS3_APPLYING_INSETS注入mPrivateFlag3 mPrivateFlags3 |= PFLAG3_APPLYING_INSETS; if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) { return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets); } else { return onApplyWindowInsets(insets); } } finally { //将PLAGS3_APPLYING_INSETS移除mPrivateFlag3 mPrivateFlag3 &= ~PFLAG3_APPLYING_INSETS; }
@Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { ... insets = updateColorViews(insets, true/animate/); insets = updateStatusGuard(insets); updateNavigationGuard(insets); ... return insets }
private WindowInsets updateColorViews(WindowInsets insets, boolean animate) { ...... updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor, navBarSize, navBarToRightEdge, 0 /rightInset/, animate && !disallowAnimate); ...... updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor, mLastTopInset, false /matchVertical/, statusBarRightInset, animate && !disallowAnimate); }
private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color, int size, boolean verticalBar, int rightMargin, boolean animate) { ...... state.view = view = new View(mContext); view.setBackgroundColor(color); view.setTransitionName(state.transitionName); view.setId(state.id); visibilityChanged = true; view.setVisibility(INVISIBLE); state.targetVisibility = VISIBLE; LayoutParams lp = new LayoutParams(resolvedWidth, resolvedHeight, resolvedGravity); lp.rightMargin = rightMargin; addView(view, lp);//向DecorView中添加StatusBar或NavigationBar ...... }
StatusBar流程:
zygote-SystemServer.main-SystemServer.run-SystemServer.startOtherServices-ActivityManagerService.systemReady-SystemServer.startSystemUi-systemUIService.onCreate-SystemUIApplication.startServicesIfNeeded-SystemBars.start-ServiceMonitor.start-SystemBars.onNoService-SystemBars.createStatusBarFromConfig(R.string.config_statusBarComponent表示PhoneStatusBar)-PhoneStatusBar.start-BaseSatusBar.start-PhoneStatusBar.createAndAddWindows-PhoneStatusBar.addStatusBarWindow-PhoneStatusBar.makeStatusBarView
其中makeStatusBarView实例化StatusBarWindow,也就是真实显示statusbar各种图标的布局,然后在addStatusBarWindow中进行添加操作:
private void addStatusBarWindow() { makeStatusBarView(); mStatusBarWindowManager = new StatusBarWindowManager(mContext); mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());//mStatusBarWindow是已经实例化的statsbar布局 }
public void add(View statusBarView, int barHeight) { ...... mWindowmanager.addView(mStatusBarView, mLp); ...... }