ViewRootImpl.setView之后的relayout流程

对接https://blog.csdn.net/chi_wy/article/details/89187791中的部分继续跟一下代码

wm是ViewManager,ViewManager是个接口,而WindowManager继承了ViewManager,WindowManagerImpl实现了WindowManager

ActivityThead.handleResumeActivity-->wm.addView-->

WindowManagerImpl.addView()--->
WindowManagerGlobal.addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow)-->{
        root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);
        root.setView(view, wparams, panelParentView);

}

ViewRootImpl.setView-->
{

1.requestLayout;

2.new InputChannel();

3.mWindowSession.addToDisplay;

4.new InputQueue();

5.mInputQueueCallback.onInputQueueCreated(mInputQueue);

6.new WindowInputEventReceiver(mInputChannel,Looper.myLooper());
}

看一下requestLayout

  @Override
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            if (ViewDebugManager.DEBUG_REQUESTLAYOUT) {
                Log.d(mTag, "requestLayout: mView = " + mView + ", this = " + this,
                        new Throwable("requestLayout"));
            }
            checkThread();
            mLayoutRequested = true;
            scheduleTraversals();
        }
    }

核心是scheduleTraversals();这个方法负责刷新绘制

  void scheduleTraversals() {
        if (ViewDebugManager.DEBUG_SCHEDULETRAVERSALS)
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "scheduleTraversals In");
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            if (ViewDebugManager.DEBUG_SCHEDULETRAVERSALS)
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "scheduleTraversals occurred");
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            if (ViewDebugManager.DEBUG_SCHEDULETRAVERSALS) {
                Log.v(mTag, "scheduleTraversals: mTraversalBarrier = " + mTraversalBarrier
                        + ",this = " + this, new Throwable("scheduleTraversals"));
            }
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            if (!mUnbufferedInputDispatch) {
                scheduleConsumeBatchedInput();
            }
            notifyRendererOfFramePending();
            if (ViewDebugManager.DEBUG_SCHEDULETRAVERSALS) Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            pokeDrawLockIfNeeded();
        }
        if (ViewDebugManager.DEBUG_SCHEDULETRAVERSALS) Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }
    final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }

 

mTraversalRunnable-->doTraversal-->performTraversals--->relayoutWindow

其中performTraversals方法开始遍历整个View树,执行View的measure,layout,draw流程  

链接:https://blog.csdn.net/chi_wy/article/details/84134320


    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {

....
        if (mSurface.isValid()) {
            //获取surface下一个帧
            frameNumber = mSurface.getNextFrameNumber();
        }
....
        //relayout
        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);
.....

   }

/frameworks/base/services/core/java/com/android/server/wm/Session.java

  @Override
    public 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) {
...
        int res = mService.relayoutWindow(this, window, seq, attrs,
                requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                outStableInsets, outsets, outBackdropFrame, cutout,
                mergedConfiguration, outSurface);
 
...
 }

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) {
....
        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client, false);
....
            if (viewVisibility != View.GONE) {
                win.setRequestedSize(requestedWidth, requestedHeight);
            }
 
            //log中输出的Relayout刷新
            if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
                    + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
 
             win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
 
            // We should only relayout if the view is visible, it is a starting window, or the
            // associated appToken is not hidden.
            final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
                    (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
                            || !win.mAppToken.isClientHidden());
            // If we are not currently running the exit animation, we need to see about starting
            // one.
            // We don't want to animate visibility of windows which are pending replacement.
            // In the case of activity relaunch child windows could request visibility changes as
            // they are detached from the main application window during the tear down process.
            // If we satisfied these visibility changes though, we would cause a visual glitch
            // hiding the window before it's replacement was available. So we just do nothing on
            // our side.
            // This must be called before the call to performSurfacePlacement.
            if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
                if (DEBUG_VISIBILITY) {
                    Slog.i(TAG_WM,
                            "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
                }
                result |= RELAYOUT_RES_SURFACE_CHANGED;
                if (!win.mWillReplaceWindow) {
                    focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
                            focusMayChange);
                }
            }
            // We may be deferring layout passes at the moment, but since the client is interested
            // in the new out values right now we need to force a layout.
            mWindowPlacerLocked.performSurfacePlacement(true /* force */);
            if (shouldRelayout) {
.....
                 result = win.relayoutVisibleWindow(result, attrChanges);
.....
///创建SurfaceControl
                 result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);

            }
 
       }
 
 
  }

3.mWindowSession.addToDisplay;

Session.addToDisplay--->WindowManagerService.addWindow---->

    public int addWindow(Session session, IWindow client, int seq,
            LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
....
        synchronized(mWindowMap) {
....
            if (token == null) {
                token = new WindowToken(this, binder, type, false, displayContent,
                        session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);

            } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                atoken = token.asAppWindowToken();
...

            }
....

....
            mInputMonitor.setUpdateInputWindowsNeededLw();

            boolean focusChanged = false;
            if (win.canReceiveKeys()) {
                focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
                        false /*updateInputWindows*/);
                if (focusChanged) {
                    imMayMove = false;
                }
            }

....
            if (imMayMove) {
                displayContent.computeImeTarget(true /* updateImeTarget */);
            }

            // Don't do layout here, the window must call
            // relayout to be displayed, so we'll do it there.
            win.getParent().assignChildLayers();

            if (focusChanged) {
                mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/);
            }
            mInputMonitor.updateInputWindowsLw(false /*force*/);
....

       }


        return res;
......

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值