Android中的GUI系統是用戶端和服務端配合的視窗系統,即後台運行了一個繪製服務,每個應用程式都是該服務端的一個用戶端,當用戶端需要繪製時,首先請求服務端建立一個視窗,然後在視窗中進行具體的視圖內容繪製;對於每個用戶端而言,他們都感覺自己獨佔了螢幕,而對於服務端而言,它會給每一個用戶端視窗分配不同的層值,並根據使用者的互動情況動態改變視窗的層值,這就給使用者造成了所謂的前台視窗和後台視窗的概念;
Android的螢幕繪製架構如:
- SurfaceFlinger進程:簡稱sf,該進程在系統開機時自動啟動,在init.rc中定義,他的作用就是給每個用戶端分配視窗,在程式中用Surface類來表示這個視窗,即每個視窗都是一個平面,而每個平面在程式中都會對應一塊螢幕緩衝區;
sf服務進程的啟動命令源碼位於./frameworks/native/cmds/surfaceflinger/;
sf服務的具體源碼位於./frameworks/native/services/surfaceflinger/;
- SystemServer進程:前面已經重點講過該進程的相關資訊了,他是zygote進程孵化出的第一個進程,裡面載入的是所有android系統運行所需的各種系統服務,當然最重要的就是Ams和Wms,而Wms正是螢幕繪圖服務端最重要的視窗管理服務,用戶端應用程式要請求視窗展示直接與Wms打交道,然後Wms進行相關的視窗管理,並通過sf的用戶端驅動介面和sf打交道,從而完成視窗內容的繪製;
Wms的具體實現源碼位於com.android.server.wm.WindowManagerService;
- Surface/Canvas類:主要用來記錄視窗的寬、高、位置、層值等相關資訊,Wms就是用他來和sf用戶端驅動打交道(新版本中實際上是通過SurfaceSession來作為紐帶了),具體的是當Surface初始化時會通過sf用戶端介面建立真正視窗需要的螢幕緩衝區;完成之後應用程式可以通過lockCanvas()來擷取一個Canvas對象,再之後便可以調用各式各樣的api完成具體內容的繪製;
注意:Surface對象並不能由應用程式直接初始化,他只對SDK內部開放,主要在ViewRootImpl中建立;不過android系統提供了一個SurfaceView可以讓應用程式來間接的使用Surface;
- Skia圖形庫:用C/C++編寫的圖形驅動庫,用來完成各種平面繪製,Canvas類中的各種drawXXX方法實際上都是交由Skia庫執行的;
Skia的具體源碼位於./external/skia/;
Canvas/Drawable/Paint的關係與區別
Canvas:畫布,所有的繪圖都需要經過他再調用底層Skia完成具體繪製,畫布一般是通過Surface完成螢幕緩衝區初始化之後擷取;
Drawable:一個抽象類別,其子類代表某個特定的圖案,比如SDK中包括了BitmapDrawable、ColorDrawable等,他僅僅是一個功能類,無法完成具體的繪製工作,但他提供了一個abstract方法draw(Canvas canvas),通過它直接轉交給canvas實際處理繪製;你可以根據需要實現自訂的Drawable;
Paint:畫筆,用來儲存圖案繪製時所用的顏色、樣式(是否有陰影、粗細、圓角、字型、對齊等),一般在canvas.drawXXX中作為參數進行使用;
以上內容若有轉載,請註明出處,歡迎訪問老唐的專欄http://blog.csdn.net/sfdev