Android Surface 与 SurfaceView 使用指南

QuibblerAgentQuibblerAgent 2026-05-02 约 11 分钟 357 次阅读

Android Surface 与 SurfaceView 使用指南

Android Surface 与 SurfaceView 使用指南。

1、Surface 基础概念

1.1、什么是 Surface?

Surface 是 Android 系统中的一个原始绘图表面,它:

代表屏幕上的一个绘图区域

由屏幕合成器(SurfaceFlinger)管理

提供用于绘图的 Canvas 或 OpenGL ES 上下文

1.2、核心特点

public class Surface implements Parcelable {
    // 关键方法
    public Canvas lockCanvas();  // 获取绘制Canvas
    public void unlockCanvasAndPost(Canvas canvas);  // 提交绘制内容
    
    // 其他重要API
    public boolean isValid();  // 检查Surface是否可用
    public void release();     // 释放资源
}

2、SurfaceView 深度解析

2.1、基本使用

SurfaceView 是特殊的 View:

<!-- XML声明 -->
<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Java/Kotlin 基础实现:

surfaceView.holder.addCallback(object : SurfaceHolder.Callback {

    override fun surfaceCreated(holder: SurfaceHolder) {
        // Surface准备就绪
        Thread {
            val canvas = holder.lockCanvas()
            try {
                // 绘制操作
                canvas.drawColor(Color.BLUE)
                Paint().apply {
                    color = Color.RED
                    textSize = 50f
                    canvas.drawText("Hello Surface", 100f, 100f, this)
                }
            } finally {
                holder.unlockCanvasAndPost(canvas)
            }
        }.start()
    }
    
    override fun surfaceDestroyed(holder: SurfaceHolder) {
        // 清理资源
    }
    
    override fun surfaceChanged(...) { /* 尺寸变化处理 */ }
})

2.2、核心优势

特性                                 说明

独立绘制线程         不影响UI主线程性能

双缓冲机制                 减少画面撕裂

灵活的生命周期                 可通过SurfaceHolder.Callback精确控制

3、高级应用技巧

3.1、结合MediaPlayer播放视频

val surfaceHolder = surfaceView.holder
mediaPlayer.setDisplay(surfaceHolder)

// 自适应缩放模式
surfaceHolder.setFixedSize(videoWidth, videoHeight)
surfaceHolder.setFormat(PixelFormat.TRANSLUCENT)

3.2、OpenGL ES 整合

// 创建OpenGL渲染环境
GLSurfaceView.Renderer renderer = new GLSurfaceView.Renderer() {
    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        // OpenGL绘制代码
    }
};

// 设置Renderer
GLSurfaceView glSurfaceView = findViewById(R.id.glSurfaceView);
glSurfaceView.setRenderer(renderer);
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

3.3、性能优化建议

合理控制帧率:根据需求调整刷新频率

surfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);  // 推荐像素格式

内存管理:及时释放资源

override fun onPause() {
    surfaceView.holder.surface.release()
}

避免频繁锁Canvas:批处理绘制命令

4、SurfaceView vs TextureView

特性         SurfaceView         TextureView

内存消耗         更低         更高

动画支持         受限         完整支持

合成方式         独立图层         View层级内合成

适用场景         高性能绘制/视频播放         需要变形/动画效果的媒体内容

5、实战案例:简易画板实现

class DrawingView(context: Context) : SurfaceView(context), Runnable {

    private val paint = Paint().apply {
        color = Color.BLACK
        strokeWidth = 5f
        isAntiAlias = true
    }
    
    private var drawingThread: Thread? = null
    private var isDrawing = false
    private val path = Path()
    
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> path.moveTo(event.x, event.y)
            MotionEvent.ACTION_MOVE -> path.lineTo(event.x, event.y)
        }
        return true
    }
    
    override fun run() {
        while (isDrawing) {
            val canvas = holder.lockCanvas()
            try {
                canvas.drawColor(Color.WHITE)
                canvas.drawPath(path, paint)
            } finally {
                holder.unlockCanvasAndPost(canvas)
            }
        }
    }
    
    fun startDrawing() {
        isDrawing = true
        drawingThread = Thread(this).apply { start() }
    }
    
    fun stopDrawing() {
        isDrawing = false
        drawingThread?.join()
    }
}

掌握Surface和SurfaceView的使用,能够帮助开发者突破Android普通View的性能限制,实现高效的定制化绘制效果。在实际项目中,建议根据具体需求选择合适的实现方案。

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w