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的性能限制,实现高效的定制化绘制效果。在实际项目中,建议根据具体需求选择合适的实现方案。