
View 和 SurfaceView 的區(qū)別
View 主要適用于主動(dòng)更新的情況下,而 SurfaceView 主要適用于被動(dòng)更新,例如頻繁地刷新。
View 在主線程中對畫面進(jìn)行刷新,而 SurfaceView 通常會通過一個(gè)子線程來進(jìn)行頁面的刷新。
View 在繪圖時(shí)沒有使用雙緩沖機(jī)制,而 SurfaceView 在底層實(shí)現(xiàn)機(jī)制中就已經(jīng)實(shí)現(xiàn)了雙緩沖機(jī)制。
總結(jié)就是,如果你的自定義View需要頻繁刷新,或者刷新時(shí)數(shù)據(jù)處理量比較大,那么你就可以考慮使用 SurfaceView 來取代 View 了。
SurfaceView擁有獨(dú)立的繪圖表面Surface,即它不與其宿主窗口共享一個(gè)Surface。由于擁有獨(dú)立的Surface,因此SurfaceView的UI就可以在一個(gè)單獨(dú)的線程中進(jìn)行繪制。
對于Android普通的控件,例如TextView,Button等,它們都是將自己的UI繪制在宿主窗口的繪圖表面上,這意味著它們的UI在是應(yīng)用線程的主線程中進(jìn)行繪制的。當(dāng)我們對UI繪制的操作花費(fèi)很多時(shí)間,就很有可能被系統(tǒng)認(rèn)為應(yīng)用程序沒有響應(yīng)了,因此就會彈出一個(gè)ANR對話框出來。
具有獨(dú)立的繪圖表面
需要在宿主窗口上挖一個(gè)洞來顯示自己
它的UI繪制可以在單獨(dú)的線程中進(jìn)行,這樣就可以進(jìn)行負(fù)責(zé)的UI繪制,并且不會影響應(yīng)用程序的主線程響應(yīng)用戶輸入。
SurfaceView內(nèi)部維護(hù)著一塊Surface用于ui數(shù)據(jù)的的繪制,同時(shí)在WindowManagerService端會創(chuàng)建一個(gè)新的繪圖對象,對應(yīng)著SurfaceFlinger的一個(gè)新的Layer,因此SurfaceView中繪制的數(shù)據(jù)就由新的Layer,而不是宿主DecorView的Layer,意思就是SurfaceView有和宿主DecorView對應(yīng)的ViewRootImpl一樣的一套繪制渲染模型,兩者分別獨(dú)立渲染。
SurfaceView的工作流程。
1.在onAttachedToWindow中進(jìn)行對SurfaceView的初始化和準(zhǔn)備工作。完成透明區(qū)域的請求,獲取WindowManagerService的本地代理對象mSession,和對繪制的監(jiān)聽addOnPreDrawListener
2.在onWindowVisibilityChanged中將被顯示時(shí),調(diào)用updateWindow
3.updateWindow,初始化MyWindow對象,用于WindowManagerService通知SurfaceView的狀態(tài)變化,mSession.relayout以請求WindowManagerService對Surface的UI進(jìn)行布局,這樣SurfaceFlinger就會為其創(chuàng)建一個(gè)獨(dú)立的Layer繪圖對象。這里同時(shí)會回調(diào)SurfaceHolder.Callback的surfaceCreated和surfaceChanged等方法,通知當(dāng)前的SurfaceView是否準(zhǔn)備好了。
4.然后我們就可以通過getHolder獲取SurfaceHolder的對象,在新線程中,通過lockCanvas鎖定畫布,然后用Cavas對象進(jìn)行繪制,內(nèi)部是通過SurfaceView的Surface對象來取得Canvas對象,該Canvas通過JNI調(diào)用到底層的Surface的Canvas進(jìn)行操作。
5.在onDetachedFromWindow中進(jìn)行對SurfaceView的清理工作。移除繪制監(jiān)聽,調(diào)用updateWindow通知回調(diào)SurfaceHolder.Callback的surfaceDestroyed,mSession移除mWindow以使WindowManagerService解除對SurfaceView的操作。
再次總結(jié),因?yàn)槠胀╒iew走的是ViewRootImpl的繪制流程,在里面有對線程進(jìn)行檢查,非主線程的話會拋異常,目的就是實(shí)現(xiàn)單線程繪制模型,同時(shí)又要接受輸入事情等。而SurfaceView有獨(dú)立的繪制機(jī)制,比如獨(dú)立的客戶端Surface,WindowManagerService中獨(dú)立的繪圖對象,SurfaceFlinger中獨(dú)立的Layer渲染。因?yàn)樗锩婵梢灾回?fù)責(zé)繪制,所以效率要更高。當(dāng)然,SurfaceView的其他處理比如輸入事件還是繼承使用了View的那一套。
參考
Android:SurfaceView 的使用(附代碼模板)
Android SurfaceView原理分析
SurfaceView原理簡述
SurfaceView原理理解和常見問題
Android視圖SurfaceView的實(shí)現(xiàn)原理分析