一、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相关文档中找到。