Adroid UI 介面繪製原理分析,adroidui
在Android APP應用的開發中,UI的展現很重要。然而,Google提供的Android UI控制項對於APP的普通開發是可以滿足的,但是需要
做一些複雜的UI那就需要自己去自訂UI控制項了。談到自訂UI控制項,想必需要先瞭解一下Adroid UI 介面繪製原理吧,Android手
機不管是對Google提供的Android控制項,還是自己定義的控制項,都需要手機對UI控制項的繪製。下面根據自己所瞭解的Adroid UI 介面繪
制原理進行一下分析:
Adroid 介面繪製實現
View類包含Surface(變數名mSurface)。Surface中包含CompatibleCanvas(變數名mCanvas)。CompatibleCanvas繼承至Canval(java.awt.Canval),其中包含一個矩陣對象Matrix(變數名mOrigMatrix)。矩陣Matrix就是一塊記憶體地區,針對View的
各種繪畫操作都儲存在此記憶體中。
每個Surface通常對應兩個buffer,一個front buffer, 一個back buffer。其中,back buffer就是canvas繪圖時對應的
bitmap (研究android_view_Surface.cpp::lockCanvas)。因此,繪畫總是在back buffer上,需要更新時,則將back buffer和
front buffer互換。
每個surface又對應一個layer, SurfaceFlinger負責將各個layer的front buffer合成(composite)繪製到螢幕上。
使用者介面方面,主要表現任務由View的各種繼承類來實現。View類的繼承關係。
當使用者請求繪製調用invalidate(),此函數會找到當前View或Viewgroup的ParentView,並調用父視圖的invalidateChild(this, r)。invalidateChild會迴圈調用父視圖的invalidateChildInParent()因此層層向上層視圖調用,直到調用到根視圖ViewRoot。ViewRoot的invalidateChildInParent調用invalidateChild,然後發送訊息讓ViewRoot進行繪製。繪製代碼在handleMessage()中的case DO_TRAVERSAL中調用了performTraversals()。
然後調用下一級視圖的draw()函數。draw函數會依次調用以下幾個函數:
background.draw(canvas)
onDraw(canvas)
dispatchDraw(canvas)
onDrawScrollBars(canvas)
在ViewGroup的dispatchDraw中會調用drawChild函數。drawChild根據子View的私人標誌位mPrivateFlags來調用子類的draw()或者dispatchDraw(canvas)。由此實現了層層向下繪製,直到最基本的View。View的dispatchDraw是一個抽象函數,繪製過程到此結束。最後ViewRoot會調用nativeShowFPS(canvas, now - sDrawTime)函數將繪製結果canvas傳遞給本地層進行顯示。