Talk Android together (121 times: View's internal process in Android 4)

Keywords: Mobile Android

Hello, officers and gentlemen. Last time we talked about an example of the internal process of View in Android. This time we will continue to talk about this example. Don't mention gossip, turn right. Let's talk about Android!

Officials, we introduced the planning of Viwe's internal process in the previous chapter, and this time we introduced its third internal process: drawing.

Drawing is mainly to draw each component, which can only be seen after the component has been drawn. Drawing function is mainly achieved through the performDraw() function, the following is its source code:

private void performDraw() {
    if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
        return;
    } else if (mView == null) {
        return;
    }

    final boolean fullRedrawNeeded = mFullRedrawNeeded || mReportNextDraw;
    mFullRedrawNeeded = false;

    mIsDrawing = true;
    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");

    boolean usingAsyncReport = false;
    if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null
            && mAttachInfo.mThreadedRenderer.isEnabled()) {
        usingAsyncReport = true;
        mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> {
            // TODO: Use the frame number
            pendingDrawFinished();
        });
    }

    try {
        boolean canUseAsync = draw(fullRedrawNeeded);
        if (usingAsyncReport && !canUseAsync) {
            mAttachInfo.mThreadedRenderer.setFrameCompleteCallback(null);
            usingAsyncReport = false;
        }
    } finally {
        mIsDrawing = false;
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }

    // For whatever reason we didn't create a HardwareRenderer, end any
    // hardware animations that are now dangling
    if (mAttachInfo.mPendingAnimatingRenderNodes != null) {
        final int count = mAttachInfo.mPendingAnimatingRenderNodes.size();
        for (int i = 0; i < count; i++) {
            mAttachInfo.mPendingAnimatingRenderNodes.get(i).endAllAnimators();
        }
        mAttachInfo.mPendingAnimatingRenderNodes.clear();
    }

    if (mReportNextDraw) {
        mReportNextDraw = false;

        // if we're using multi-thread renderer, wait for the window frame draws
        if (mWindowDrawCountDown != null) {
            try {
                mWindowDrawCountDown.await();
            } catch (InterruptedException e) {
                Log.e(mTag, "Window redraw count down interrupted!");
            }
            mWindowDrawCountDown = null;
        }

        if (mAttachInfo.mThreadedRenderer != null) {
            mAttachInfo.mThreadedRenderer.setStopped(mStopped);
        }

        if (LOCAL_LOGV) {
            Log.v(mTag, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
        }

        if (mSurfaceHolder != null && mSurface.isValid()) {
            SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::postDrawFinished);
            SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();

            sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
        } else if (!usingAsyncReport) {
            if (mAttachInfo.mThreadedRenderer != null) {
                mAttachInfo.mThreadedRenderer.fence();
            }
            pendingDrawFinished();
        }
    }
}

You can see that its core function is achieved through the draw() function, which will be described in detail in the next chapter.

Ladies and gentlemen, here's an example of the internal process of View in Androd. For further examples, listen to the decomposition next time! __________

Posted by dynamicallystatic on Mon, 01 Apr 2019 14:48:30 -0700