相关源码:
\frameworks\base\core\java\android\app\Activity.java
\frameworks\base\core\java\android\app\ActivityThread.java
\frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
\frameworks\base\core\java\android\app\servertransaction\ResumeActivityItem.java
\frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
\frameworks\base\core\java\android\view\WindowManagerImpl.java
\frameworks\base\core\java\android\view\WindowManagerGlobal.java
\frameworks\base\core\java\android\view\ViewRootImpl.java
\frameworks\base\services\core\java\com\android\server\wm\Session.java

activity的启动可以参考:
《Android P窗口机制之Activity启动流程》

从attach()方法说起

Activity

创建Window:从Activity的启动流程得知,最终会调用Activity中的attach来初始化window。

final void attach(Context context, ActivityThread aThread,        Instrumentation instr, IBinder token, int ident,        Application application, Intent intent, ActivityInfo info,        CharSequence title, Activity parent, String id,        NonConfigurationInstances lastNonConfigurationInstances,        Configuration config, String referrer, IVoiceInteractor voiceInteractor,        Window window, ActivityConfigCallback activityConfigCallback) {    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);    }    mUiThread = Thread.currentThread();    mMainThread = aThread;    mInstrumentation = instr;    mToken = token;    mIdent = ident;    mApplication = application;    mIntent = intent;    mReferrer = referrer;    mComponent = intent.getComponent();    mActivityInfo = info;    mTitle = title;    mParent = parent;    mEmbeddedID = id;    mLastNonConfigurationInstances = lastNonConfigurationInstances;    if (voiceInteractor != null) {        if (lastNonConfigurationInstances != null) {            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;        } else {            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,                    Looper.myLooper());        }    }    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);    setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());    enableAutofillCompatibilityIfNeeded();}

关键点:mWindow = new PhoneWindow(this),创建了一个PhoneWindow对象。并设置一些回调。

ActivityThread

Activity创建后会执行:handleResumeActivity()方法,该方法中Window加载了DecorView

@Overridepublic void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,        String reason) {    // If we are getting ready to gc after going to the background, well    // we are back active so skip it.    unscheduleGcIdler();    mSomeActivitiesChanged = true;    // TODO Push resumeArgs into the activity for consideration    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);    if (r == null) {        // We didn't actually resume the activity, so skipping any follow-up actions.        return;    }    final Activity a = r.activity;    if (localLOGV) {        Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity                + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);    }    final int forwardBit = isForward            ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;    // If the window hasn't yet been added to the window manager,    // and this guy didn't finish itself or start another activity,    // then go ahead and add the window.    boolean willBeVisible = !a.mStartedActivity;    if (!willBeVisible) {        try {            willBeVisible = ActivityManager.getService().willActivityBeVisible(                    a.getActivityToken());        } catch (RemoteException e) {            throw e.rethrowFromSystemServer();        }    }    if (r.window == null && !a.mFinished && willBeVisible) {        r.window = r.activity.getWindow();        View decor = r.window.getDecorView();        decor.setVisibility(View.INVISIBLE);        ViewManager wm = a.getWindowManager();        WindowManager.LayoutParams l = r.window.getAttributes();        a.mDecor = decor;        l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;        l.softInputMode |= forwardBit;        if (r.mPreserveWindow) {            a.mWindowAdded = true;            r.mPreserveWindow = false;            // Normally the ViewRoot sets up callbacks with the Activity            // in addView->ViewRootImpl#setView. If we are instead reusing            // the decor view we have to notify the view root that the            // callbacks may have changed.            ViewRootImpl impl = decor.getViewRootImpl();            if (impl != null) {                impl.notifyChildRebuilt();            }        }        if (a.mVisibleFromClient) {            if (!a.mWindowAdded) {                a.mWindowAdded = true;                wm.addView(decor, l);            } else {                // The activity will get a callback for this {@link LayoutParams} change                // earlier. However, at that time the decor will not be set (this is set                // in this method), so no action will be taken. This call ensures the                // callback occurs with the decor set.                a.onWindowAttributesChanged(l);            }        }        // If the window has already been added, but during resume        // we started another activity, then don't yet make the        // window visible.    } else if (!willBeVisible) {        if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");        r.hideForNow = true;    }    // Get rid of anything left hanging around.    cleanUpPendingRemoveWindows(r, false /* force */);    // The window is now visible if it has been added, we are not    // simply finishing, and we are not starting another activity.    if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {        if (r.newConfig != null) {            performConfigurationChangedForActivity(r, r.newConfig);            if (DEBUG_CONFIGURATION) {                Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "                        + r.activity.mCurrentConfig);            }            r.newConfig = null;        }        if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);        WindowManager.LayoutParams l = r.window.getAttributes();        if ((l.softInputMode                & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)                != forwardBit) {            l.softInputMode = (l.softInputMode                    & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))                    | forwardBit;            if (r.activity.mVisibleFromClient) {                ViewManager wm = a.getWindowManager();                View decor = r.window.getDecorView();                wm.updateViewLayout(decor, l);            }        }        r.activity.mVisibleFromServer = true;        mNumVisibleActivities++;        if (r.activity.mVisibleFromClient) {            r.activity.makeVisible();        }    }    r.nextIdle = mNewActivities;    mNewActivities = r;    if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);    Looper.myQueue().addIdleHandler(new Idler());}

关键点1:wm.addView(decor, l),加载DecorView到window中去。DecorView中包含了StatusBar和NavigationBar的View,包含应用程序MainActivity的ContentView
关键点2:wm.updateViewLayout(decor, l),更新window

Window更新机制

WindowManagerImpl

源码:frameworks\base\core\java\android\view\WindowManagerImpl.java
最终执行WindowManagerImpl中的updateViewLayout():

@Overridepublic void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {    applyDefaultToken(params);    mGlobal.updateViewLayout(view, params);}

WindowManagerGlobal

源码:\frameworks\base\core\java\android\view\WindowManagerGlobal.java

public void updateViewLayout(View view, ViewGroup.LayoutParams params) {    if (view == null) {        throw new IllegalArgumentException("view must not be null");    }    if (!(params instanceof WindowManager.LayoutParams)) {        throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");    }    final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;    view.setLayoutParams(wparams);    synchronized (mLock) {        int index = findViewLocked(view, true);        ViewRootImpl root = mRoots.get(index);        mParams.remove(index);        mParams.add(index, wparams);        root.setLayoutParams(wparams, false);    }}

设置新的params,调用ViewRootImpl.setLayoutParams()方法来设置。

ViewRootImpl

源码:\frameworks\base\core\java\android\view\ViewRootImpl.java

void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {    synchronized (this) {        final int oldInsetLeft = mWindowAttributes.surfaceInsets.left;        final int oldInsetTop = mWindowAttributes.surfaceInsets.top;        final int oldInsetRight = mWindowAttributes.surfaceInsets.right;        final int oldInsetBottom = mWindowAttributes.surfaceInsets.bottom;        final int oldSoftInputMode = mWindowAttributes.softInputMode;        final boolean oldHasManualSurfaceInsets = mWindowAttributes.hasManualSurfaceInsets;        if (DEBUG_KEEP_SCREEN_ON && (mClientWindowLayoutFlags                & WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0                && (attrs.flags&WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) == 0) {            Slog.d(mTag, "setLayoutParams: FLAG_KEEP_SCREEN_ON from true to false!");        }        // Keep track of the actual window flags supplied by the client.        mClientWindowLayoutFlags = attrs.flags;        // Preserve compatible window flag if exists.        final int compatibleWindowFlag = mWindowAttributes.privateFlags                & WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;        // Transfer over system UI visibility values as they carry current state.        attrs.systemUiVisibility = mWindowAttributes.systemUiVisibility;        attrs.subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility;        mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs);        if ((mWindowAttributesChangesFlag                & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {            // Recompute system ui visibility.            mAttachInfo.mRecomputeGlobalAttributes = true;        }        if ((mWindowAttributesChangesFlag                & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0) {            // Request to update light center.            mAttachInfo.mNeedsUpdateLightCenter = true;        }        if (mWindowAttributes.packageName == null) {            mWindowAttributes.packageName = mBasePackageName;        }        mWindowAttributes.privateFlags |= compatibleWindowFlag;        if (mWindowAttributes.preservePreviousSurfaceInsets) {            // Restore old surface insets.            mWindowAttributes.surfaceInsets.set(                    oldInsetLeft, oldInsetTop, oldInsetRight, oldInsetBottom);            mWindowAttributes.hasManualSurfaceInsets = oldHasManualSurfaceInsets;        } else if (mWindowAttributes.surfaceInsets.left != oldInsetLeft                || mWindowAttributes.surfaceInsets.top != oldInsetTop                || mWindowAttributes.surfaceInsets.right != oldInsetRight                || mWindowAttributes.surfaceInsets.bottom != oldInsetBottom) {            mNeedsRendererSetup = true;        }        applyKeepScreenOnFlag(mWindowAttributes);        if (newView) {            mSoftInputMode = attrs.softInputMode;            requestLayout();        }        // Don't lose the mode we last auto-computed.        if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)                == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {            mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode                    & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)                    | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);        }        mWindowAttributesChanged = true;        scheduleTraversals();    }}

根据params计算了一系列的高度和宽度,包括上,下,左,右的间距等等。

关键点:scheduleTraversals(),最后会调用performTraversals

void scheduleTraversals() {    if (!mTraversalScheduled) {        mTraversalScheduled = true;        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();        mChoreographer.postCallback(                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);        if (!mUnbufferedInputDispatch) {            scheduleConsumeBatchedInput();        }        notifyRendererOfFramePending();        pokeDrawLockIfNeeded();    }}

执行了mTraversalRunnable,

final class TraversalRunnable implements Runnable {    @Override    public void run() {        doTraversal();    }}final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void doTraversal() {    if (mTraversalScheduled) {        mTraversalScheduled = false;        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);        if (mProfile) {            Debug.startMethodTracing("ViewAncestor");        }        performTraversals();        if (mProfile) {            Debug.stopMethodTracing();            mProfile = false;        }    }}

关键点:performTraversals()
performTraversals方法对View进行测量、布局和绘制。

private void performTraversals() {//省略一部分代码//...relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//省略一部分代码//...}**关键点:relayoutWindow()**```javaprivate int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,        boolean insetsPending) throws RemoteException {//省略一部分代码//...    int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,            (int) (mView.getMeasuredWidth() * appScale + 0.5f),            (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,            insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,            mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,            mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,            mPendingMergedConfiguration, mSurface);            //省略一部分代码//...    return relayoutResult;}

通过mWindowSession进行进程间通信,最终调用到WindowManagerService中去。完成Window更新。

Session

源码:\frameworks\base\services\core\java\com\android\server\wm\Session.java

@Overridepublic int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,        int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,        Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,        Rect outStableInsets, Rect outsets, Rect outBackdropFrame,        DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,        Surface outSurface) {    if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "            + Binder.getCallingPid());    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);    int res = mService.relayoutWindow(this, window, seq, attrs,            requestedWidth, requestedHeight, viewFlags, flags, frameNumber,            outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,            outStableInsets, outsets, outBackdropFrame, cutout,            mergedConfiguration, outSurface);    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);    if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "            + Binder.getCallingPid());    return res;}

通过mService调用了relayoutWindow,mService就是WinodwManagerService.

WinodwManagerService

源码:\frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java

public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,            int requestedWidth, int requestedHeight, int viewVisibility, int flags,            long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,            DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,            Surface outSurface) {            //省略一部分代码//...//关键点1,根据session和client获取WindowState对象WindowState win = windowForClientLocked(session, client, false);//省略一部分代码//...//关键点2,更新windowresult = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);//省略一部分代码//...}

WindowState

更多相关文章

  1. [1] Android主要源代码组成
  2. Android Studio 活动的启动模式 standard singleTop singleTask
  3. Android存储系统之源码篇
  4. Android 实例子源代码文件下载地址380个合集
  5. 安卓布局属性代码中文注解
  6. [Android]android源码下载&Eclipse关联android源码
  7. Android 源码结构
  8. Android窗口机制(二)Window,PhoneWindow,DecorView,setContentView源
  9. Android 之 Eclipse 导入 Android 源码

随机推荐

  1. Android应用中使用Popupmenu
  2. Android安卓开发官方文档国内镜像
  3. android欢迎界面并执行任务
  4. Android中添加syslog功能
  5. SMS Library in Android
  6. android历史版本对应的api等级
  7. android ndk开发-环境搭建
  8. Android 打开Activity后,不显示键盘
  9. Android几款著名的ActiveSync客户端
  10. android 在SD卡创建文件夹