Bootstrap

什么是 SurfaceView?其使用场景及示例有哪些?

SurfaceView 核心解析


1. 基本概念
  • 定义SurfaceView 是 Android 中一种特殊的视图组件,提供独立于主 UI 线程的绘图表面(Surface),允许在子线程中进行高性能图形渲染。
  • 关键特性
    • 双缓冲机制:减少绘制时的屏幕闪烁。
    • 独立 Surface:与主窗口分离的绘图层,支持更灵活的刷新控制。
    • 低延迟渲染:适用于高频刷新场景(如游戏、视频)。

2. 核心优势(对比普通 View)
特性SurfaceView普通 View
绘制线程子线程主 UI 线程
刷新效率高(直接操作画布)低(依赖 invalidate()
适用场景高频刷新/复杂图形静态/简单动态内容
叠加显示可置于其他视图下方默认按视图层级叠加

3. 典型使用场景
  1. 视频播放器
    • 解码后的视频帧直接渲染到 Surface(如 MediaPlayer + SurfaceHolder)。
  2. 游戏开发
    • 实时渲染游戏画面(OpenGL ES/Vulkan 结合 Surface)。
  3. 相机预览
    • 通过 Camera2 API 将预览数据输出到 Surface。
  4. 自定义动态图表
    • 高频更新的传感器数据可视化。

4. 基础代码示例
public class CustomSurfaceView extends SurfaceView 
    implements SurfaceHolder.Callback, Runnable {

    private SurfaceHolder mHolder;
    private Thread mRenderThread;
    private boolean isDrawing;

    public CustomSurfaceView(Context context) {
        super(context);
        mHolder = getHolder();
        mHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isDrawing = true;
        mRenderThread = new Thread(this);
        mRenderThread.start();
    }

    @Override
    public void run() {
        while (isDrawing) {
            Canvas canvas = mHolder.lockCanvas();
            try {
                // 在子线程中绘制内容(示例:绘制红色背景)
                canvas.drawColor(Color.RED);
            } finally {
                mHolder.unlockCanvasAndPost(canvas);
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDrawing = false;
        try {
            mRenderThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 其他回调方法省略...
}
5. 进阶用法(结合 GLSurfaceView)
// OpenGL ES 渲染示例(Kotlin)
class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {

    init {
        setEGLContextClientVersion(3)
        renderer = object : GLSurfaceView.Renderer {
            override fun onDrawFrame(gl: GL10?) {
                // OpenGL 绘制逻辑
                GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
            }
            // 其他回调方法...
        }
        renderMode = RENDERMODE_CONTINUOUSLY
    }
}
6. 注意事项
  1. 生命周期管理
    • 需在 surfaceDestroyed() 中停止绘制线程,避免内存泄漏。
  2. 性能优化
    • 使用 SurfaceHolder.lockCanvas() 获取画布后,尽量缩小锁定区域。
  3. 替代方案
    • 对于需要视图变换(旋转/缩放)的场景,优先考虑 TextureView
    • Android 8.0+ 推荐使用 SurfaceControlViewHost 跨进程渲染。

📌 关键选择:优先使用 SurfaceView 处理高频刷新内容,若需与其他视图混合叠加且需要硬件加速,则选择 TextureView

;