Android 圖形圖像之從上到下

Android 圖形圖像顯示系統(tǒng):
四大組件中Activity負(fù)責(zé)UI的展示和交互,對(duì)于Activity的生命周期常常如下:
oncreate->onresume()-onpause-onstop-ondestroy
通常在oncreate中設(shè)置對(duì)應(yīng)的布局UI,當(dāng)執(zhí)行到onresume時(shí)候我們就能看到界面的展示。
根據(jù)這個(gè)流程我們通過AOSP源碼 我們可以將圖形圖像的流程和相關(guān)關(guān)鍵類歸納如下:
在Android Framework Client層
1、ActivityThread,Activity
負(fù)責(zé)啟動(dòng)android進(jìn)程和android虛擬機(jī),加載Activity,控制Activity生命周期執(zhí)行。在activity生命周期的oncreate階段加載對(duì)應(yīng)的布局文件,從第一個(gè)DecorView 開始構(gòu)建頂層FrameLayout容器,同時(shí)根據(jù)對(duì)應(yīng)的布局文件控件層級(jí)關(guān)系加載進(jìn)來(lái)。在ActivityThread handleResumeActivity 中開始將當(dāng)前的activity布局的DecorView 正式添加到WindowsManager中來(lái),并同時(shí)調(diào)用wm.addView為DecorView的根節(jié)點(diǎn)信息(ViewRootImpl),并且調(diào)用ViewRootImpl 中requestFitSystemWindows以觸發(fā)圖形圖像的測(cè)量布局和繪制。

2、WindowManager,WindowManagerGlobal
負(fù)責(zé)維護(hù)當(dāng)前Window的控件中狀態(tài)。

3、ViewRootImpl,View 負(fù)責(zé)控件的具體測(cè)量繪制。
圖像的具體繪制由scheduleTraversals函數(shù)調(diào)度 performTraversals完成完整的一整套android 測(cè)量,位置布局,繪制流程。我們目前不關(guān)心控件的測(cè)量和布局,僅關(guān)心圖像的呈現(xiàn)。關(guān)于繪制部分詳細(xì)的可以流程在draw方法中可以看到具體實(shí)現(xiàn)

 private void draw(boolean fullRedrawNeeded) {
        Surface surface = mSurface;
        if (!surface.isValid()) {
            return;
        }
        if (DEBUG_FPS) {
            trackFPS();
        }
  ....
        if (mSurfaceHolder != null) {
            // The app owns the surface, we won't draw.
            dirty.setEmpty();
            if (animating && mScroller != null) {
                mScroller.abortAnimation();
            }
            return;
        }
        if (fullRedrawNeeded) {
            mAttachInfo.mIgnoreDirtyState = true;
            dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
        }
  ....
        if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
            if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
             ....
                mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
            } else {
              ...
                if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
                    return;
                }
            }
        }
...
    }

在draw中 程序會(huì)根據(jù)是否開啟硬件加速選擇執(zhí)行軟件繪制或者硬件繪制。對(duì)應(yīng)軟件繪制的情況,主要是利用surface獲取到Canvas,然后調(diào)用View.draw 繪制到對(duì)應(yīng)的畫布上。

 private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
            boolean scalingRequired, Rect dirty) {

        // Draw with software renderer.
        final Canvas canvas;
...
        canvas = mSurface.lockCanvas(dirty);
        try {
    
            if (!canvas.isOpaque() || yoff != 0 || xoff != 0) {
                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
            }

            dirty.setEmpty();
            mIsAnimating = false;
            mView.mPrivateFlags |= View.PFLAG_DRAWN;
     
            try {
                canvas.translate(-xoff, -yoff);
                if (mTranslator != null) {
                    mTranslator.translateCanvas(canvas);
                }
                canvas.setScreenDensity(scalingRequired ? mNoncompatDensity : 0);
                attachInfo.mSetIgnoreDirtyState = false;

                mView.draw(canvas);

                drawAccessibilityFocusedDrawableIfNeeded(canvas);
            } finally {
                if (!attachInfo.mSetIgnoreDirtyState) {
                    // Only clear the flag if it was not set during the mView.draw() call
                    attachInfo.mIgnoreDirtyState = false;
                }
            }
        } finally {
            try {
                surface.unlockCanvasAndPost(canvas);
            } catch (IllegalArgumentException e) {
                Log.e(mTag, "Could not unlock surface", e);
                mLayoutRequested = true;    // ask wm for a new surface next time.
                //noinspection ReturnInsideFinallyBlock
                return false;
            }

            if (LOCAL_LOGV) {
                Log.v(mTag, "Surface " + surface + " unlockCanvasAndPost");
            }
        }
        return true;
    }

4 、Cavas.java SkiaCanvas.cpp
對(duì)于軟繪制而言,最終回到了Canvas提供的一系列繪制函數(shù)例如 drawRect,drawArc,drawLine等。以drawArc 為列,Canvas的最終會(huì)調(diào)用到對(duì)應(yīng) JNI層的Canvas繪制,具體的繪制則有對(duì)應(yīng)hwui庫(kù)實(shí)現(xiàn)相關(guān)繪制,具體路徑為(frameworks/base/libs/hwui),對(duì)應(yīng)到native層的SkiaCanvas。

5、渲染到顯示流程:
創(chuàng)建空surface,空的canvas,relayout階段開始分配native層Surface,在draw階段開始根據(jù)surface lockcavas獲取canvas,獲取canvas過程中Canvas 通過native層鎖定獲取bufferquee,在bufferqueue中dequeuebuffer獲取GraphicBuffer,并且根據(jù)鎖定的區(qū)域重新設(shè)置bitmap,將bitmap的的像素地址和grphaicbuffer中申請(qǐng)的內(nèi)存地址綁定。同時(shí)為畫布設(shè)置新的bitmap(例如skcanvas 設(shè)置skbitmap)。獲取到Canvas過后,在Canvas的任何操縱 比如 drawarc即反映到bitmap上。繪制結(jié)束后,unlockcanvas 會(huì)向bufferqueue中queuebuffer 告知新的幀圖像數(shù)據(jù)準(zhǔn)備好;由surfacefliner取出合成或送顯。

4、ThreadedRenderer 負(fù)責(zé)View的硬件繪制

在Framework Server層。

4、ThreadedRenderer

未完待續(xù)....

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容