Android SurfaceView基礎(chǔ)用法詳解
Android 游戲開(kāi)發(fā)框架核心組件
核心組件介紹
SurfaceView 介紹
- SurfaceView 介紹 SurfaceView 就是帶 Surface 的 view,它是一個(gè) View,是 View 的子類,所以和其他 View 一樣,可以在屏幕上展示東西接收用戶輸入,具有 View 的生命周期回調(diào)函數(shù),如 onMeasure、onLayout、onDraw、onTouchEvent 等
- SurfaceView 帶有獨(dú)立的 Surface(獨(dú)立與 window 的 surface),這可以讓子線程在獨(dú)立的 Surface 上面繪制東西,進(jìn)行 SurfaceView 的界面繪制,這個(gè)子線程就叫做渲染線程,但是要讓獨(dú)立的 Surface 上面的東西在 View 上面展示出來(lái),需要 post 一個(gè)消息給主線程,目的是把該 Surface 中 canvas 上的東西繪制到 View 的真正的畫(huà)布上面(window 的 surface 的 canvas上),這樣就可以把 UI 線程空閑出來(lái)處理用戶的交互
- Surface 可能被銷毀,它只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed() 之間有效,這只是說(shuō) Surface 創(chuàng)建和銷毀的時(shí)候會(huì)回到前面兩個(gè)方法,所以要確保渲染線程訪問(wèn)的是合法有效的 surface
- SurfaceHolder.CallBack 是通過(guò) SurfaceView 的 SurfaceHolder 的 addCallback 來(lái)設(shè)置給 SurfaceHolder 的,讓 SurfaceView 實(shí)現(xiàn) CallBack 并設(shè)置給 SurfaceHolder,SurfaceView 就可以監(jiān)聽(tīng)這個(gè)獨(dú)立 Surface 的創(chuàng)建和銷毀了。
sdk 中的介紹
SurfaceView是視圖(View)的繼承類,這個(gè)視圖里內(nèi)嵌了一個(gè)專門(mén)用于繪制的Surface。你可以控制這個(gè)Surface的格式和尺寸。Surfaceview控制這個(gè)Surface的繪制位置。
surface是縱深排序(Z-ordered)的,這表明它總在自己所在窗口的后面。surfaceview提供了一個(gè)可見(jiàn)區(qū)域,只有在這個(gè)可見(jiàn)區(qū)域內(nèi) surface 部分內(nèi)容才可見(jiàn),可見(jiàn)區(qū)域外的部分不可見(jiàn)。
surface 的排版顯示受到視圖層級(jí)關(guān)系的影響,它的兄弟視圖結(jié)點(diǎn)會(huì)在頂端顯示。這意味者 surface
的內(nèi)容會(huì)被它的兄弟視圖遮擋,這一特性可以用來(lái)放置遮蓋物(overlays)(例如,文本和按鈕等控件)。注意,如果 surface 上面有透明控件,那么它的每次變化都會(huì)引起框架重新計(jì)算它和頂層控件之間的透明效果,這會(huì)影響性能。
你可以通過(guò) surfaceHolder 接口訪問(wèn)這個(gè)surface,getHolder() 方法可以得到這個(gè)接口。
surfaceview 變得可見(jiàn)時(shí),surface被創(chuàng)建;surfaceview隱藏前,surface被銷毀。這樣能節(jié)省資源。如果你要查看 surface 被創(chuàng)建和銷毀的時(shí)機(jī),可以重載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder) surfaceView 的核心在于提供了兩個(gè)線程:UI線程和渲染線程。
這里應(yīng)注意:
1. 所有 SurfaceView 和 SurfaceHolder.Callback 的方法都會(huì)在UI線程里調(diào)用,一般來(lái)說(shuō)就是應(yīng)用程序主線程。所以渲染線程所要訪問(wèn)的各種變量應(yīng)該作同步處理。
2. 由于surface可能被銷毀,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之間有效,所以要確保渲染線程訪問(wèn)的是合法有效的
surface。
SurfaceHolder 介紹
SurfaceHolder 是對(duì) SurfaceView 的 Surface 的包裝,不但在 SurfaceHolder.callback 接口中負(fù)責(zé) Surface 創(chuàng)建和銷毀的回調(diào),而且還對(duì) Surface 的關(guān)鍵方法 LockCanvas()、unLockCanvasAndPost() 方法進(jìn)行了線程安全的包裝,所以 SurfaceHolder 是 Surface 對(duì)象的持有者,負(fù)責(zé) Surface 的生命周期中的對(duì) Surface 操作的方法的調(diào)用
臟矩形 Rect dirty,是指標(biāo)記這塊矩形區(qū)域的數(shù)據(jù)作廢,也就是需要重寫(xiě)繪制的矩形區(qū)域,LockCanvas(Rect dirty),可以指定一個(gè)矩形區(qū)域,讓 Surface 中的 Canvas 上部分?jǐn)?shù)據(jù)重繪。
SurfaceView、SurfaceHolder、Surface 之間的關(guān)系
SurfaceView 使用的步驟
- 獲取到 SurfaceView 對(duì)應(yīng)的 SurfaceHolder,給 SurfaceHolder 添加一個(gè) SurfaceHolder.callback 對(duì)象。
- 創(chuàng)建渲染線程對(duì)象
- 在子線程中開(kāi)始在 Surface 上面繪制圖形,因?yàn)镾urfaceView沒(méi)有對(duì)我們暴露 Surface,而只是暴露了 Surface 的包裝器 SurfaceHolder,所以使用 SurfaceHolder 的 lockCanvas()獲取 Surface 上面指定區(qū)域的 Canvas,在該 Canvas 上繪制圖形,繪制結(jié)束后,使用 SurfaceHolder 的 unlockCanvasAndPost()方法解鎖 Canvas,并且讓 UI 線程把 Surface 上面的東西繪制到 View 的 Canvas 上面
SurfaceView 使用的 demo
public class GameUI extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private RenderThread renderThread; private boolean isDraw = false;// 控制繪制的開(kāi)關(guān) public GameUI(Context context) { super(context); holder = this.getHolder(); holder.addCallback(this); renderThread = new RenderThread(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { isDraw = true; renderThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { isDraw = false; } /** * 繪制界面的線程 * * @author Administrator * */ private class RenderThread extends Thread { @Override public void run() { // 不停繪制界面 while (isDraw) { drawUI(); } super.run(); } } /** * 界面繪制 */ public void drawUI() { Canvas canvas = holder.lockCanvas(); try { drawCanvas(canvas); } catch (Exception e) { e.printStackTrace(); } finally { holder.unlockCanvasAndPost(canvas); } } private void drawCanvas(Canvas canvas) { // 在 canvas 上繪制需要的圖形 } }
到此這篇關(guān)于Android SurfaceView基礎(chǔ)用法詳解的文章就介紹到這了,更多相關(guān)Android SurfaceView基礎(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flutter實(shí)現(xiàn)抖音點(diǎn)贊效果
抖音的點(diǎn)贊效果在第一次看到的時(shí)候,總有一種眼前一亮的感覺(jué)。一邊看視頻,還能在視頻上點(diǎn)贊,而且整個(gè)屏幕都能夠點(diǎn)贊,并伴隨動(dòng)畫(huà),還是很炫酷的。今天我們用Flutter來(lái)實(shí)現(xiàn)一下這個(gè)效果2021-05-05Android小知識(shí)之OkHttp的2種請(qǐng)求方式詳解
OkHttp可以說(shuō)是如今最為流行的網(wǎng)絡(luò)請(qǐng)求框架之一,下面這篇文章主要給大家介紹了關(guān)于Android小知識(shí)之OkHttp的2種請(qǐng)求方式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-10-10android webview 簡(jiǎn)單瀏覽器實(shí)現(xiàn)代碼
android webview 簡(jiǎn)單瀏覽器實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-05-05Android開(kāi)關(guān)控件Switch的使用案例
今天小編就為大家分享一篇關(guān)于Android開(kāi)關(guān)控件Switch的使用案例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03Android多線程斷點(diǎn)續(xù)傳下載實(shí)現(xiàn)代碼
這篇文章主要介紹了Android多線程斷點(diǎn)續(xù)傳下載實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Android AsyncTask實(shí)現(xiàn)機(jī)制詳細(xì)介紹及實(shí)例代碼
這篇文章主要介紹了Android AsyncTask實(shí)現(xiàn)機(jī)制詳細(xì)介紹及實(shí)例代碼的相關(guān)資料,這里附有示例代碼,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下2016-12-12java,Android:在eclipse中的快捷鍵(經(jīng)典收藏)
下面的快捷鍵是常用的,本人就本身喜好且常用的收拾一下,現(xiàn)在曬出來(lái)與大家分享,感興趣的朋友可以了解小哦2013-01-01Android 兩個(gè)Service的相互監(jiān)視實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 兩個(gè)Service的相互監(jiān)視實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10