请先看完上一篇文章再看此章:

####以下代码基于API25

推荐博客 

分析Activity里的WindowManager的获取

image.png

看看Window的setWindowManager和getWindowManager2个方法:

image.png

image.png

可以确定WindowManager的具体实现类是:WindowManagerImpl

WindowManager类本身是一个接口,又继承了另外一个接口ViewManager 

image.png

ViewManager的作用注释说的很清楚:让你对Activity添加或者删除子View

image.png

WindowManager的addView方法

image.png

image.png

WindowManagerImpl又会去调用WindowManagerGlobal类

public void addView(View view, ViewGroup.LayoutParams params,        Display display, Window parentWindow) {...    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;    }}

这都是关键核心的代码 

 root.setView(view, wparams, panelParentView);
/** * We have one child */public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {    synchronized (this) {        if (mView == null) {            mView = view;         。。。                      requestLayout();            if ((mWindowAttributes.inputFeatures                    & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {                mInputChannel = new InputChannel();            }            mForceDecorViewVisibility = (mWindowAttributes.privateFlags                    & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;            try {                mOrigWindowType = mWindowAttributes.type;                mAttachInfo.mRecomputeGlobalAttributes = true;                collectViewAttributes();                res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,                        getHostVisibility(), mDisplay.getDisplayId(),                        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,                        mAttachInfo.mOutsets, 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();                }            }            if (mTranslator != null) {                mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);            }            mPendingOverscanInsets.set(0, 0, 0, 0);            mPendingContentInsets.set(mAttachInfo.mContentInsets);            mPendingStableInsets.set(mAttachInfo.mStableInsets);            mPendingVisibleInsets.set(0, 0, 0, 0);            mAttachInfo.mAlwaysConsumeNavBar =                    (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR) != 0;            mPendingAlwaysConsumeNavBar = mAttachInfo.mAlwaysConsumeNavBar;            if (DEBUG_LAYOUT) Log.v(mTag, "Added window " + mWindow);            if (res < WindowManagerGlobal.ADD_OKAY) {                mAttachInfo.mRootView = null;                mAdded = false;                mFallbackEventHandler.setView(null);                unscheduleTraversals();                setAccessibilityFocus(null, null);                switch (res) {                    case WindowManagerGlobal.ADD_BAD_APP_TOKEN:                    case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:                        throw new WindowManager.BadTokenException(                                "Unable to add window -- token " + attrs.token                                + " is not valid; is your activity running?");                    case WindowManagerGlobal.ADD_NOT_APP_TOKEN:                        throw new WindowManager.BadTokenException(                                "Unable to add window -- token " + attrs.token                                + " is not for an application");                    case WindowManagerGlobal.ADD_APP_EXITING:                        throw new WindowManager.BadTokenException(                                "Unable to add window -- app for token " + attrs.token                                + " is exiting");                    case WindowManagerGlobal.ADD_DUPLICATE_ADD:                        throw new WindowManager.BadTokenException(                                "Unable to add window -- window " + mWindow                                + " has already been added");                    case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:                        // Silently ignore -- we would have just removed it                        // right away, anyway.                        return;                    case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:                        throw new WindowManager.BadTokenException("Unable to add window "                                + mWindow + " -- another window of type "                                + mWindowAttributes.type + " already exists");                    case WindowManagerGlobal.ADD_PERMISSION_DENIED:                        throw new WindowManager.BadTokenException("Unable to add window "                                + mWindow + " -- permission denied for window type "                                + mWindowAttributes.type);                    case WindowManagerGlobal.ADD_INVALID_DISPLAY:                        throw new WindowManager.InvalidDisplayException("Unable to add window "                                + mWindow + " -- the specified display can not be found");                    case WindowManagerGlobal.ADD_INVALID_TYPE:                        throw new WindowManager.InvalidDisplayException("Unable to add window "                                + mWindow + " -- the specified window type "                                + mWindowAttributes.type + " is not valid");                }                throw new RuntimeException(                        "Unable to add window -- unknown error code " + res);            }            if (view instanceof RootViewSurfaceTaker) {                mInputQueueCallback =                    ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();            }            if (mInputChannel != null) {                if (mInputQueueCallback != null) {                    mInputQueue = new InputQueue();                    mInputQueueCallback.onInputQueueCreated(mInputQueue);                }                mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,                        Looper.myLooper());            }            view.assignParent(this);            mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;            mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;            if (mAccessibilityManager.isEnabled()) {                mAccessibilityInteractionConnectionManager.ensureConnection();            }            if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {                view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);            }            // Set up the input pipeline.            CharSequence counterSuffix = attrs.getTitle();            mSyntheticInputStage = new SyntheticInputStage();            InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);            InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,                    "aq:native-post-ime:" + counterSuffix);            InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);            InputStage imeStage = new ImeInputStage(earlyPostImeStage,                    "aq:ime:" + counterSuffix);            InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);            InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,                    "aq:native-pre-ime:" + counterSuffix);            mFirstInputStage = nativePreImeStage;            mFirstPostImeInputStage = earlyPostImeStage;            mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;        }    }}

  • requestLayout方法

@Overridepublic void requestLayout() {    if (!mHandlingLayoutInLayoutRequest) {        checkThread();        mLayoutRequested = true;        scheduleTraversals();    }}

 看checkThread,这个异常大家应该比较熟悉了吧。

 image.png

image.png

官方的解释就是告诉硬件渲染器做好准备,马上一帧画面就要来了。

image.png

  • res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,        getHostVisibility(), mDisplay.getDisplayId(),        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,        mAttachInfo.mOutsets, mInputChannel);

        这里的mWindowSession

        image.png

        

        image.png

        上面的WindowManager即是WindowManagerService:

        image.png

        

     image.png

     看看Session的addToDisplay方法

    image.png

   正好调用的是WindowManagerService的方法,注意这里的window是ViewRootImpl中的W类,可以发现这个类是跨进程通讯的。

   WindowManagerService的addWindow方法比较麻烦,后续再研究。