android Window(一)从setConetView说起

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 主要干两件事情

  1. 如果mDecor没有初始化generateDecor()初始化
  2. 如果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;
    }

猜你喜欢

转载自www.cnblogs.com/mingfeng002/p/9140366.html