Activity的源码
首先从setContentView这里调用的mWindow的 setConetView()
private Window mWindow; public void setContentView(View view) { getWindow().setContentView(view); initWindowDecorActionBar(); } public Window getWindow() { return mWindow; }
那么这mWindow什么时候初始化?final void attach(...) {
attachBaseContext(context); mFragments.attachHost(null /*parent*/); mWindow = new PhoneWindow(this, window, activityConfigCallback); mWindow.setWindowControllerCallback(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0) { mWindow.setUiOptions(info.uiOptions); } //... //给window设置windowManger mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); if (mParent != null) { mWindow.setContainer(mParent.getWindow()); } mWindowManager = mWindow.getWindowManager(); mCurrentConfig = config; mWindow.setColorMode(info.colorMode); }
可以看到这个mWindow 其实是一个PhoneWindow的实例,那么phoneWindow干了什么
可以查看PhoneWindow的源码
152 // This is the view in which the window contents are placed. It is either 153 // mDecor itself, or a child of mDecor where the contents go. 154 private ViewGroup mContentParent; 390 @Override 391 public void setContentView(View view, ViewGroup.LayoutParams params) { 392 // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window 393 // decor, when theme attributes and the like are crystalized. Do not check the feature 394 // before this happens. 395 if (mContentParent == null) { 396 installDecor(); 397 } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) { 398 mContentParent.removeAllViews(); 399 } 400 401 if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { 402 view.setLayoutParams(params); 403 final Scene newScene = new Scene(mContentParent, view); 404 transitionTo(newScene); 405 } else { 406 mContentParent.addView(view, params); 407 } 408 final Callback cb = getCallback(); 409 if (cb != null && !isDestroyed()) { 410 cb.onContentChanged(); 411 } 412 }
这里setContentView 主要是 先判断mContentParent是否初始化如果没有初始化调用installDecor 。然后将view添加到mContentParent的ViewGroup中
那么 installDecor 做了些什么
private DecorView mDecor; 3551 private void installDecor() { 3552 if (mDecor == null) { 3553 mDecor = generateDecor(); 3554 mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 3555 mDecor.setIsRootNamespace(true); 3556 if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) { 3557 mDecor.postOnAnimation(mInvalidatePanelMenuRunnable); 3558 } 3559 } 3560 if (mContentParent == null) { 3561 mContentParent = generateLayout(mDecor); 3562 3563 // Set up decor part of UI to ignore fitsSystemWindows if appropriate. 3564 mDecor.makeOptionalFitsSystemWindows(); 3565 3566 final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById( 3567 R.id.decor_content_parent); 3568 3569 if (decorContentParent != null) { 3570 mDecorContentParent = decorContentParent; 3571 mDecorContentParent.setWindowCallback(getCallback()); 3572 if (mDecorContentParent.getTitle() == null) { 3573 mDecorContentParent.setWindowTitle(mTitle); 3574 } 3575 3576 final int localFeatures = getLocalFeatures(); 3577 for (int i = 0; i < FEATURE_MAX; i++) { 3578 if ((localFeatures & (1 << i)) != 0) { 3579 mDecorContentParent.initFeature(i); 3580 } 3581 } 3582 3583 mDecorContentParent.setUiOptions(mUiOptions); 3584 //setIcon,setLogo ... 3608 } else { //setTitle ...3627 } //... } 3686 }
installDecor 主要干两件事情
- 如果mDecor没有初始化generateDecor()初始化
- 如果mContentParent 没有初始化generateLayout()初始化
generateDecor 就是返回一个新的DecorView
3199 protected DecorView generateDecor() { 3200 return new DecorView(getContext(), -1); 3201 }
DecorView 主要处理各种和交互的事件
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker{ //... }
generateLayout()给activity的根布设置各种属性
protected ViewGroup generateLayout(DecorView decor) { // Apply data from current theme. //主要设置各种FLAG,属性 //R.styleable.Window_windowIsFloating //set FEATURE_NO_TITLE //set FEATURE_ACTION_BAR //set FEATURE_ACTION_BAR_OVERLAY //set FLAG_TRANSLUCENT_STATUS //... final WindowManager windowService = (WindowManager) getContext().getSystemService( Context.WINDOW_SERVICE); if (windowService != null) { final Display display = windowService.getDefaultDisplay(); final boolean shouldUseBottomOutset = display.getDisplayId() == Display.DEFAULT_DISPLAY || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0; if (shouldUseBottomOutset && a.hasValue(R.styleable.Window_windowOutsetBottom)) { if (mOutsetBottom == null) mOutsetBottom = new TypedValue(); a.getValue(R.styleable.Window_windowOutsetBottom, mOutsetBottom); } } //set menu if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) { addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); } else { clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); } // Non-floating windows on high end devices must put up decor beneath the system bars and // therefore must know about visibility changes of those. if (!mIsFloating && ActivityManager.isHighEndGfx()) { if (!targetPreL && a.getBoolean( R.styleable.Window_windowDrawsSystemBarBackgrounds, false)) { setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags()); } } if (!mForcedStatusBarColor) { mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000); } if (!mForcedNavigationBarColor) { mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000); } if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { if (a.getBoolean( R.styleable.Window_windowCloseOnTouchOutside, false)) { setCloseOnTouchOutsideIfNotSet(true); } } WindowManager.LayoutParams params = getAttributes(); if (!hasSoftInputMode()) { params.softInputMode = a.getInt( R.styleable.Window_windowSoftInputMode, params.softInputMode); } if (a.getBoolean(R.styleable.Window_backgroundDimEnabled, mIsFloating)) { /* All dialogs should have the window dimmed */ if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) { params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; } if (!haveDimAmount()) { params.dimAmount = a.getFloat( android.R.styleable.Window_backgroundDimAmount, 0.5f); } } if (params.windowAnimations == 0) { params.windowAnimations = a.getResourceId( R.styleable.Window_windowAnimationStyle, 0); } // The rest are only done if this window is not embedded; otherwise, // the values are inherited from our container. if (getContainer() == null) { if (mBackgroundDrawable == null) { if (mBackgroundResource == 0) { mBackgroundResource = a.getResourceId( R.styleable.Window_windowBackground, 0); } if (mFrameResource == 0) { mFrameResource = a.getResourceId(R.styleable.Window_windowFrame, 0); } mBackgroundFallbackResource = a.getResourceId( R.styleable.Window_windowBackgroundFallback, 0); if (false) { System.out.println("Background: " + Integer.toHexString(mBackgroundResource) + " Frame: " + Integer.toHexString(mFrameResource)); } } mElevation = a.getDimension(R.styleable.Window_windowElevation, 0); mClipToOutline = a.getBoolean(R.styleable.Window_windowClipToOutline, false); mTextColor = a.getColor(R.styleable.Window_textColor, Color.TRANSPARENT); } // Inflate the window decor. int layoutResource; int features = getLocalFeatures(); if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) { layoutResource = R.layout.screen_swipe_dismiss; } //... //主要设置activity的各种样式 fullSrceen,notitle... mDecor.startChanging(); View in = mLayoutInflater.inflate(layoutResource, null); decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); mContentRoot = (ViewGroup) in; ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); if (contentParent == null) { throw new RuntimeException("Window couldn't find content container view"); } if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) { ProgressBar progress = getCircularProgressBar(false); if (progress != null) { progress.setIndeterminate(true); } } if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) { registerSwipeCallbacks(); } // setup -- of background and title -- that only applies // to top-level windows. mDecor.finishChanging(); return contentParent; }