View绘制流程

2020-06-22  本文已影响0人  wildeyess

view的绘制流程是一个比较复杂且难懂的知识,根据这篇博客自己做一些总结
一文彻底搞懂Android View的绘制流程

1. Window,DecorView 与 ViewRootImp 的三角恋关系

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

    ....
    // 创建Activity,会调用Activity的onCreate方法
    // 从而完成DecorView的创建
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        handleResumeActivity(r.tolen, false, r.isForward, !r.activity..mFinished && !r.startsNotResumed);
    }
}

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;
    // 调用Activity的onResume方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    if (r != null) {
        final Activity a = r.activity;
        ...
        if (r.window == null &&& !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            // 得到DecorView
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            // 得到了WindowManager,WindowManager是一个接口
            // 并且继承了接口ViewManager
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (a.mVisibleFromClient) {
                a.mWindowAdded = true;
                // WindowManager的实现类是WindowManagerImpl,
                // 所以实际调用的是WindowManagerImpl的addView方法
                wm.addView(decor, l);
            }
        }
    }
}

public final class WindowManagerImpl implements WindowManager {
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
    ...
    
    @Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mDisplay, mParentWindow);
    }
    ...
}

public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
}
private void performTraversals() {
    ...
    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
    ...
    //执行测量流程
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...
    //执行布局流程
    performLayout(lp, desiredWindowWidth, desiredWindowHeight);
    ...
    //执行绘制流程
    performDraw();
}

2. MeasureSpec

measurespec就是测量view的一个数据封装类。它包含了两个信息

3. 总结measure流程

measre流程图.png

4. Layout流程

view的layout流程和measure流程类型,具体的目的就是要根据每个view的长宽,根据相应viewGroup实现类的规则放置view的位置。确定view的left,top,right,bottom的值。

5. draw流程

view的绘制。流程同上,一般来说针对的就是weight目录下的东西,和viewGroup就没啥关系了,根据各自textview,imageview等实现类,画出相应内容即可。

6. 关于自定义view

自定义View的内容推荐一个比较好的课程Hencoder

上一篇 下一篇

猜你喜欢

热点阅读