Android SurfaceView基礎(chǔ)用法詳解
Android 游戲開發(fā)框架核心組件
核心組件介紹
SurfaceView 介紹
- SurfaceView 介紹 SurfaceView 就是帶 Surface 的 view,它是一個 View,是 View 的子類,所以和其他 View 一樣,可以在屏幕上展示東西接收用戶輸入,具有 View 的生命周期回調(diào)函數(shù),如 onMeasure、onLayout、onDraw、onTouchEvent 等
- SurfaceView 帶有獨(dú)立的 Surface(獨(dú)立與 window 的 surface),這可以讓子線程在獨(dú)立的 Surface 上面繪制東西,進(jìn)行 SurfaceView 的界面繪制,這個子線程就叫做渲染線程,但是要讓獨(dú)立的 Surface 上面的東西在 View 上面展示出來,需要 post 一個消息給主線程,目的是把該 Surface 中 canvas 上的東西繪制到 View 的真正的畫布上面(window 的 surface 的 canvas上),這樣就可以把 UI 線程空閑出來處理用戶的交互
- Surface 可能被銷毀,它只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed() 之間有效,這只是說 Surface 創(chuàng)建和銷毀的時候會回到前面兩個方法,所以要確保渲染線程訪問的是合法有效的 surface
- SurfaceHolder.CallBack 是通過 SurfaceView 的 SurfaceHolder 的 addCallback 來設(shè)置給 SurfaceHolder 的,讓 SurfaceView 實(shí)現(xiàn) CallBack 并設(shè)置給 SurfaceHolder,SurfaceView 就可以監(jiān)聽這個獨(dú)立 Surface 的創(chuàng)建和銷毀了。
sdk 中的介紹
SurfaceView是視圖(View)的繼承類,這個視圖里內(nèi)嵌了一個專門用于繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
surface是縱深排序(Z-ordered)的,這表明它總在自己所在窗口的后面。surfaceview提供了一個可見區(qū)域,只有在這個可見區(qū)域內(nèi) surface 部分內(nèi)容才可見,可見區(qū)域外的部分不可見。
surface 的排版顯示受到視圖層級關(guān)系的影響,它的兄弟視圖結(jié)點(diǎn)會在頂端顯示。這意味者 surface
的內(nèi)容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控件)。注意,如果 surface 上面有透明控件,那么它的每次變化都會引起框架重新計(jì)算它和頂層控件之間的透明效果,這會影響性能。
你可以通過 surfaceHolder 接口訪問這個surface,getHolder() 方法可以得到這個接口。
surfaceview 變得可見時,surface被創(chuàng)建;surfaceview隱藏前,surface被銷毀。這樣能節(jié)省資源。如果你要查看 surface 被創(chuàng)建和銷毀的時機(jī),可以重載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder) surfaceView 的核心在于提供了兩個線程:UI線程和渲染線程。
這里應(yīng)注意:
1. 所有 SurfaceView 和 SurfaceHolder.Callback 的方法都會在UI線程里調(diào)用,一般來說就是應(yīng)用程序主線程。所以渲染線程所要訪問的各種變量應(yīng)該作同步處理。
2. 由于surface可能被銷毀,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之間有效,所以要確保渲染線程訪問的是合法有效的
surface。
SurfaceHolder 介紹
SurfaceHolder 是對 SurfaceView 的 Surface 的包裝,不但在 SurfaceHolder.callback 接口中負(fù)責(zé) Surface 創(chuàng)建和銷毀的回調(diào),而且還對 Surface 的關(guān)鍵方法 LockCanvas()、unLockCanvasAndPost() 方法進(jìn)行了線程安全的包裝,所以 SurfaceHolder 是 Surface 對象的持有者,負(fù)責(zé) Surface 的生命周期中的對 Surface 操作的方法的調(diào)用
臟矩形 Rect dirty,是指標(biāo)記這塊矩形區(qū)域的數(shù)據(jù)作廢,也就是需要重寫繪制的矩形區(qū)域,LockCanvas(Rect dirty),可以指定一個矩形區(qū)域,讓 Surface 中的 Canvas 上部分?jǐn)?shù)據(jù)重繪。
SurfaceView、SurfaceHolder、Surface 之間的關(guān)系
SurfaceView 使用的步驟
- 獲取到 SurfaceView 對應(yīng)的 SurfaceHolder,給 SurfaceHolder 添加一個 SurfaceHolder.callback 對象。
- 創(chuàng)建渲染線程對象
- 在子線程中開始在 Surface 上面繪制圖形,因?yàn)镾urfaceView沒有對我們暴露 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;// 控制繪制的開關(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Flutter實(shí)現(xiàn)抖音點(diǎn)贊效果
抖音的點(diǎn)贊效果在第一次看到的時候,總有一種眼前一亮的感覺。一邊看視頻,還能在視頻上點(diǎn)贊,而且整個屏幕都能夠點(diǎn)贊,并伴隨動畫,還是很炫酷的。今天我們用Flutter來實(shí)現(xiàn)一下這個效果2021-05-05android webview 簡單瀏覽器實(shí)現(xiàn)代碼
android webview 簡單瀏覽器實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-05-05Android多線程斷點(diǎn)續(xù)傳下載實(shí)現(xiàn)代碼
這篇文章主要介紹了Android多線程斷點(diǎn)續(xù)傳下載實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(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)在曬出來與大家分享,感興趣的朋友可以了解小哦2013-01-01Android 兩個Service的相互監(jiān)視實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 兩個Service的相互監(jiān)視實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10