Android N Graphics之应用侧的surface的创建

来源:互联网 发布:数据分析python 编辑:程序博客网 时间:2024/05/31 19:44

我们知道的是在ViewRootImpl的setView函数中调用了requestLayout函数,我们从这个函数中去分析一下surface的创建流程

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

这里能看到的是这里回去调用scheduleTraversals接口来继续实现:

    void scheduleTraversals() {    if (!mTraversalScheduled) {        mTraversalScheduled = true;        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();        mChoreographer.postCallback(                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);        if (!mUnbufferedInputDispatch) {            scheduleConsumeBatchedInput();        }        notifyRendererOfFramePending();        pokeDrawLockIfNeeded();    }}

这里能看到的是会发送一个消息来处理mTraversalRunnable这个Runnable,

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

这时候能发现这里其实是调用doTraversal来说实现的,可以看到的是doTraversal其实是调用performTraversals,这个函数巨长。

    void doTraversal() {    if (mTraversalScheduled) {        mTraversalScheduled = false;        mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);        if (mProfile) {            Debug.startMethodTracing("ViewAncestor");        }        performTraversals();        if (mProfile) {            Debug.stopMethodTracing();            mProfile = false;        }    }}

performTraversals接口太长了,这里就不分析了,我们重点关注一下surface的创建,其实是通过relayoutWindow来完成的,

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,        boolean insetsPending) throws RemoteException {    float appScale = mAttachInfo.mApplicationScale;    boolean restore = false;    if (params != null && mTranslator != null) {        restore = true;        params.backup();        mTranslator.translateWindowLayout(params);    }    if (params != null) {        if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);    }    mPendingConfiguration.seq = 0;    //Log.d(mTag, ">>>>>> CALLING relayout");    if (params != null && mOrigWindowType != params.type) {        // For compatibility with old apps, don't crash here.        if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {            Slog.w(mTag, "Window type can not be changed after "                    + "the window is added; ignoring change of " + mView);            params.type = mOrigWindowType;        }    }    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,            mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,            mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,            mSurface);    mPendingAlwaysConsumeNavBar =            (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0;    //Log.d(mTag, "<<<<<< BACK FROM relayout");    if (restore) {        params.restore();    }    if (mTranslator != null) {        mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);        mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets);        mTranslator.translateRectInScreenToAppWindow(mPendingContentInsets);        mTranslator.translateRectInScreenToAppWindow(mPendingVisibleInsets);        mTranslator.translateRectInScreenToAppWindow(mPendingStableInsets);    }    return relayoutResult;}

我们可以看到在relayoutWindow接口中调用了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,            mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,            mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,            mSurface);

可以看到这里relayout中会返回一个surface 这个surface其实就是wms中完成创建的。

当WMS中返回surface给应用的时候,这时候我们就能在其上绘图了。

原创粉丝点击