一、Surface的基本概念
Surface是Android系統中一個重要的原語,它是一塊屏幕的抽象表示。它提供了一個支持繪製、更改尺寸、透明度、格式和管理SurfaceView的生命周期的接口。在Android應用程序中,Surface通常表示一個可以渲染、處理用戶輸入、與其他SurfaceView進行組合的視圖元素。
在不同的場景下,Surface可以有不同的實現方式:SurfaceView、TextureView、GLSurfaceView等等。SurfaceView是其中應用最為廣泛的一種實現方式,因為在面向用戶的應用程序中,通過SurfaceView可以提供流暢的UI交互和動畫效果。
二、SurfaceView的使用
SurfaceView是Android系統提供的一種底層視圖,它可以用於自定義繪製以及更高效地渲染大量視圖。
下面是一個簡單的SurfaceView實現代碼:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Thread drawThread;
private volatile boolean running = false;
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
running = true;
drawThread = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
draw();
}
}
});
drawThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO: Implement surfaceChanged()
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
running = false;
try {
drawThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void draw() {
SurfaceHolder holder = getHolder();
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
// 繪製
holder.unlockCanvasAndPost(canvas);
}
}
}
在該實現中,我們重寫了SurfaceView的三個生命周期方法,分別是surfaceCreated、surfaceChanged和surfaceDestroyed。在surfaceCreated中,我們創建了一個繪製線程,在循環中不斷地調用draw()方法來進行繪製工作。在surfaceDestroyed中,我們停止了繪製線程,調用join()方法等待其結束。
三、SurfaceView的局限性
儘管SurfaceView提供了一個強大的繪製框架,但是在實際開發中,我們也要考慮到其局限性。在特定的場景下,SurfaceView可能會出現一些問題,例如:卡頓、閃爍、裂屏等等。
為了解決這些問題,我們可以採用一些優化手段,例如:
四、TextureView的使用
TextureView是Android系統提供的一種基於硬件加速的視圖,它可以在不同Surface之間進行無縫切換,並且支持疊加和混合。在一些高級應用程序中,如果需要同時顯示多個Surface,我們可以選擇使用TextureView實現。
下面是一個簡單的TextureView實現代碼:
public class MyTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private Thread drawThread;
private volatile boolean running = false;
private SurfaceTexture surfaceTexture;
public MyTextureView(Context context, AttributeSet attrs) {
super(context, attrs);
setSurfaceTextureListener(this);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
running = true;
this.surfaceTexture = surfaceTexture;
drawThread = new Thread(new Runnable() {
@Override
public void run() {
while (running) {
draw();
}
}
});
drawThread.start();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
// TODO: Implement onSurfaceTextureSizeChanged()
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
running = false;
try {
drawThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
// TODO: Implement onSurfaceTextureUpdated()
}
private void draw() {
if (surfaceTexture == null) {
return;
}
Canvas canvas = lockCanvas();
if (canvas != null) {
// 繪製
unlockCanvasAndPost(canvas);
}
}
}
在該實現中,我們實現了TextureView.SurfaceTextureListener,用於監聽SurfaceTexture的生命周期事件。在onSurfaceTextureAvailable中,我們創建了一個繪製線程,在循環中不斷地調用draw()方法來進行繪製工作。在onSurfaceTextureDestroyed中,我們停止了繪製線程,調用join()方法等待其結束。
五、GLSurfaceView的使用
GLSurfaceView是Android系統提供的一種可與OpenGL ES結合使用的視圖,它可以對3D場景進行實時渲染。在需要實現動態圖像和高級圖形效果時,我們可以選擇使用GLSurfaceView實現。
下面是一個簡單的GLSurfaceView實現代碼:
public class MyGLSurfaceView extends GLSurfaceView implements Renderer {
private FloatBuffer vertexBuffer;
private float[] vertices = {0f, 1f, -1f, -1f, 1f, -1f};
public MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2);
setRenderer(this);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 初始化
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
gl.glClearColor(0f, 0f, 0f, 0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO: Implement onSurfaceChanged()
}
@Override
public void onDrawFrame(GL10 gl) {
// 渲染
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glColor4f(0f, 1f, 0f, 1f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.length / 2);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
在該實現中,我們重寫了GLSurfaceView的三個生命周期方法,分別是onSurfaceCreated、onSurfaceChanged和onDrawFrame。在onSurfaceCreated中,我們初始化了一些OpenGL ES相關的屬性和參數。在onDrawFrame中,我們對3D場景進行渲染操作,具體內容可以在OpenGL ES相關文檔中找到。
原創文章,作者:KRTND,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/371617.html
微信掃一掃
支付寶掃一掃