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ù)....