Android WindowManagerService解析(6)

前面说过,所有的UI的绘制最终调用的都是WindowManager的addView方法,另外从前面我们也可以知道,我们操作的是WindowManagerImpl对象的addView方法,下面我们先来看看addView方法。

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

上面调用的是WindowManagerGlobal的addView方法,下面我们来看看这个方法。

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {

    final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;

    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方法。

下面看看ViewRootImpl的setView方法。

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    requestLayout();
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
            getHostVisibility(), mDisplay.getDisplayId(),
            mAttachInfo.mContentInsets, mInputChannel);
}

首先看看requestLayout方法

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

继续看看scheduleTraversals方法

final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
        mChoreographer.postCallback(
                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        scheduleConsumeBatchedInput();
    }
}

下面看看mTraversalRunnable的实现

final class TraversalRunnable implements Runnable {
    @Override
    public void run() {
        doTraversal();
    }
}

调用的是doTraversal方法。

void doTraversal() {
    performTraversals();
}

最终调用performTraversals方法

private void performTraversals() {
    WindowManager.LayoutParams lp = mWindowAttributes;
    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);

    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);

    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);

    performLayout(lp, desiredWindowWidth, desiredWindowHeight);

    performDraw();
}

上面看到整个绘制流程分为measure,layout,draw几步。

measure
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
    mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
layout
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
        int desiredWindowHeight) {
    final View host = mView;
    host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
}
draw
private void performDraw() {
    draw(fullRedrawNeeded);
}
private void draw(boolean fullRedrawNeeded) {
    // 硬件加速
    if (!dirty.isEmpty() || mIsAnimating) {
        if (attachInfo.mHardwareRenderer != null && attachInfo.mHardwareRenderer.isEnabled()) {
            attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
                    animating ? null : mCurrentDirty);
        } else {
            if (attachInfo.mHardwareRenderer != null &&
                    !attachInfo.mHardwareRenderer.isEnabled() &&
                    attachInfo.mHardwareRenderer.isRequested()) {

                try {
                    attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                            mHolder.getSurface());
                } catch (OutOfResourcesException e) {
                    handleOutOfResourcesException(e);
                    return;
                }

                mFullRedrawNeeded = true;
                scheduleTraversals();
                return;
            }

            // 软件绘制
            if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
                return;
            }
        }
    }
}
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
        boolean scalingRequired, Rect dirty) {
    Canvas canvas;
    canvas = mSurface.lockCanvas(dirty);
    mView.draw(canvas);
    surface.unlockCanvasAndPost(canvas);
    return true;
}

这里写图片描述

以Activity的绘制为例,Activity是通过Window进行操作,Window是通过WindowManager来进行操作,WindowManager是通过ViewRootImp来进行操作,ViewRootImpl是通过surface进行绘制,surface相当于一个画布,Canvas是画布的操作者。

这里写图片描述

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值