在一般的Android程序中屑埋,UI都是在主線程處理,但是痰滋,有些可能比較復(fù)雜的動(dòng)畫會(huì)卡頓主線程摘能,如相機(jī)续崖,為了解決這個(gè)問(wèn)題,Android提供了SurfaceView团搞,即在非主線程繪制UI严望。
SurfaceView在android.view包下,從Android1.0開(kāi)始支持逻恐。
public class MySurface extends SurfaceView implements Runnable{}
從中可以看出像吻,我們?cè)谑褂?code>SurfaceView時(shí),一般是自定義一個(gè)類复隆,并繼承SurfaceView
和Runnable
拨匆,熟悉Java的應(yīng)該能知道,Runnable
是實(shí)現(xiàn)多線程的接口挽拂,由此可見(jiàn)惭每,我們定義的MySurface
有多線程的特征。
那SurfaceView
又是什么呢亏栈?
從官方文檔看台腥,SurfaceView
繼承自android.view.View,也就是說(shuō)绒北,SurfaceView
也是和ImageView
览爵,TextView
類似的一個(gè)普通的View。
然后再看看官方對(duì)SurfaceView
的介紹:
第一句提供一個(gè)嵌入在View樹(shù)镇饮,專用于繪制Surface
,View樹(shù)我想大家都知道類似如下箕母,可以用Android Tool:View Hierarchy查看
那什么是Surface呢储藐?
從中可以看到,
Surface
繼承自Object
而不是View
嘶是,且實(shí)現(xiàn)了Parcelable
钙勃,可見(jiàn)Surface
不是一個(gè)傳統(tǒng)意義上的View
。再看看官方介紹
介紹很簡(jiǎn)短的一句話:由屏幕顯示內(nèi)容合成器(screen compositor)所管理的原始緩沖區(qū)的句柄聂喇,從中可以看到辖源,
Surface
是個(gè)句柄,通過(guò)這個(gè)句柄希太,可以獲得原始緩沖區(qū)及其內(nèi)容克饶,原始緩沖區(qū)用于保存當(dāng)前窗口的像素?cái)?shù)據(jù)。
從Surface
的公開(kāi)方法中誊辉,可以看到有一個(gè)lockCanvas
方法矾湃,傳入一個(gè)矩形區(qū)域,返回一個(gè)Canvas
堕澄。
Canvas
大家應(yīng)該很熟悉邀跃,從字面直譯是畫布的意思霉咨,也就是說(shuō),你可以在Canvas
這塊畫布上繪制你想要的圖像拍屑,實(shí)際上也是這個(gè)用途
看一下
lockCanvas
的介紹
從Surface
獲取一塊畫布用于繪制途戒,在繪制結(jié)束后,調(diào)用者必須執(zhí)行unlockCanvasAndPost(Canvas)
來(lái)將新繪制的內(nèi)容發(fā)送到Surface
僵驰。
再看看參數(shù)inOutDirty
:調(diào)用者想要重新繪制的一塊廢棄區(qū)域喷斋,這個(gè)方法可以被用于擴(kuò)展dirty區(qū)域,比如像縮放Surface
矢渊,調(diào)用者也可以傳遞null
继准,如果是這樣的話,整個(gè)Surface
應(yīng)該被重新繪制矮男。
而unlockCanvasAndPost(Canvas)
這個(gè)方法則是將Canvas
中繪制的內(nèi)容發(fā)送給Surface
移必。
由此可見(jiàn),雖然Surface
沒(méi)有繼承自View
毡鉴,但是它擁有一塊可繪制區(qū)域用于繪制內(nèi)容崔泵,但是因?yàn)樗鼪](méi)有繼承自View
,所以不能直接用于View
樹(shù)猪瞬。
說(shuō)到這里憎瘸,應(yīng)該能明白SurfaceView
是什么了吧,接著看SurfaceView
官方文檔:
You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen
:“你可以控制Surface
的格式陈瘦,甚至尺寸幌甘,和位置”,從這里可以看出痊项,SurfaceView存在的意義就是將不可以插入View hierarchy的Surface
轉(zhuǎn)為可以插入的SurfaceView
锅风。
The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
Surface
是在Z軸的,所以它應(yīng)該在SurfaceView
的底部鞍泉,SurfaceView
在自己身上打了個(gè)洞以便讓Surface
能被看到皱埠,View hierarchy會(huì)正確的顯示Surface
的位置,其他的View
也可以出現(xiàn)在它的上方咖驮,這可以用于將一個(gè)按鈕放置在Surface
的上方边器,需要注意的是,將一個(gè)透明的按鈕放置在Surface
的上方托修,每次Surface
的變化都會(huì)導(dǎo)致按鈕的重新繪制忘巧。
再看看這句Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by calling getHolder()
“需要訪問(wèn)底層的Surface
,你可以通過(guò)提供的SurfaceHolder
來(lái)訪問(wèn)诀黍,SurfaceHolder
可以通過(guò)getHolder()
得到”袋坑。
The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestoryed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.
只有SurfaceView
可見(jiàn)是,Surface
才會(huì)被創(chuàng)建,你可以繼承surfaceCreated
和surfaceDestoryed
獲得枣宫。
到此婆誓,SurfaceView
是什么應(yīng)該能明白了吧。