Android WindowManagerService解析(6)

来源:互联网 发布:java实施是做什么的 编辑:程序博客网 时间:2024/06/07 15:54

前面说过,所有的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方法

@Overridepublic 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是画布的操作者。

这里写图片描述

阅读全文
0 0