美文网首页
view绘制流程

view绘制流程

作者: nich | 来源:发表于2022-08-01 17:08 被阅读0次

上节setcontentview的时候生成Decorview,那他怎么绑定到window上去的呢。

activitythread.java

@Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
     。。。省略
       //Resume the activity
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }

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;
                   //WindowsManager调用addview把decorview加进去
                    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.
        }

windowmanage调用addview方法,然后点击进去会跑到WindowManagerGlobal方法
   
WindowManagerGlobal.java的addview方法
新建viewrootimpl方法
 root = new ViewRootImpl(view.getContext(), display);

            view.setLayoutParams(wparams);

            mViews.add(view);// DecorView
            mRoots.add(root);
            mParams.add(wparams);

            // do this last because it fires off messages to start doing things
            try {
                root.setView(view, wparams, panelParentView, userId);
            } catch (RuntimeException e) {
                // BadTokenException or InvalidDisplayException, clean up.
                if (index >= 0) {
                    removeViewLocked(index, true);
                }
                throw e;
            }
这里有几个类
WindowManagerImpl、WindowManagerGlobal、ViewRootImpl
WindowManagerImpl:确定 View  属于哪个屏幕,哪个父窗口
WindowManagerGlobal:管理整个进程 所有的窗口信息
ViewRootImpl:WindowManagerGlobal 实际操作者,操作自己的窗口

接下来只要看ViewRootImpl.setview方法
requestLayout();// 请求遍历
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId,
mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
mTempControls);// 将窗口添加到WMS上面 WindowManagerService
点击事件处理
view.assignParent(this)//设置parent
主要看requestLayout

 @Override
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread();//检查是不是当前线程,就是创建viewrootimpl的线程
            mLayoutRequested = true;
            scheduleTraversals();查看这个方法
        }
    }

//演舞者调用主要看mTraversalRunnable这个方法
mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

走到performTraversals这个方法

measureHierarchy(host, lp, mView.getContext().getResources(),
                            desiredWindowWidth, desiredWindowHeight);//预测量
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//布局窗口
performMeasure
performLayout
performDraw

总结

1.handleResumeActivity
2.windowmanage的 wm.addView(decor, l);
3.WindowManagerGlobal.addview
4.ViewRootImpl.setview

  1. requestLayout()
    6.mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
  2. performTraversals里面performMeasure,performLayout,performDraw

相关文章

网友评论

      本文标题:view绘制流程

      本文链接:https://www.haomeiwen.com/subject/imjrwrtx.html