Android--SurfaceView使用详解
发布日期:2021-05-10 12:46:41 浏览次数:22 分类:精选文章

本文共 3616 字,大约阅读时间需要 12 分钟。

SurfaceView 是 Android 系统中一个核心的视图绘图组件,主要用于在应用程序中实现高效的图形绘制和渲染。作为 View 的继承类,SurfaceView 内嵌了一个用于绘制的 Surface 组件,开发者可以通过它来控制 Surface 的格式、尺寸以及绘制位置。SurfaceView 的核心特性在于支持 Z-ordered(即纵深排序)绘制,这意味着它始终位于其所在窗口的后方。此外,SurfaceView 提供了一个可见区域,仅在这个区域内的 Surface 部分内容才会被显示,而区域外的内容则不可见。

SurfaceView 的特性

  • 高效的图形绘制:SurfaceView 支持在主线程之外的线程中进行绘制,这可以避免主线程被阻塞,从而提升应用程序的响应速度。
  • Z-ordering:SurfaceView 内部的 Surface 组件支持纵深排序,这对于复杂的 UI 组成(如放置遮盖物)非常有用。
  • 资源管理:SurfaceView 会自动管理 Surface 的生命周期,仅在可见时创建,隐藏时销毁,从而节省资源。
  • 回调机制:通过 SurfaceHolder.Callback 接口,开发者可以监听 SurfaceView 的生命周期变化,如创建和销毁事件。
  • 使用 SurfaceView 的步骤

  • 继承 SurfaceView 并实现 SurfaceHolder.Callback 接口:通过实现回调接口,开发者可以接收 SurfaceView 的生命周期事件。
  • 获取 SurfaceHolder 对象:调用 SurfaceView.getHolder() 方法获取 SurfaceHolder 实例。
  • 添加回调:调用 SurfaceHolder.addCallback() 方法,将自己的回调对象注册到 SurfaceHolder 中。
  • 绘制操作
    • 锁定画布:通过 SurfaceHolder.lockCanvas() 获取 Canvas 对象,并锁定画布。
    • 绘制内容:在 Canvas 上执行绘图操作。
    • 解锁并提交:调用 SurfaceHolder.unlockCanvasAndPost() 方法,解锁画布并提交绘图内容。
  • SurfaceHolder 的作用

    SurfaceHolder 类是 SurfaceView 的控制器,用于管理 Surface 的绘制和资源。以下是其主要方法:

    • addCallback(SurfaceHolder.Callback callback):注册回调对象。
    • lockCanvas():锁定画布,允许在 Canvas 对象上进行绘图操作。
    • lockCanvas(Rect dirty):锁定特定区域的画布,优化内存使用。
    • unlockCanvasAndPost(Canvas canvas):解锁画布并提交绘图内容。

    示例应用

    以下是一个简单的 SurfaceView 应用示例,展示了如何在 UI 线程和渲染线程之间进行协调:

    public class ViewTest extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));
    }
    class MyView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder holder;
    private MyThread myThread;
    public MyView(Context context) {
    super(context);
    holder = this.getHolder();
    holder.addCallback(this);
    myThread = new MyThread(holder);
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // 当 Surface 的格式或大小发生变化时触发
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    myThread.isRun = true;
    myThread.start();
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    myThread.isRun = false;
    }
    }
    class MyThread extends Thread {
    private SurfaceHolder holder;
    public boolean isRun;
    public MyThread(SurfaceHolder holder) {
    this.holder = holder;
    isRun = true;
    }
    @Override
    public void run() {
    int count = 0;
    while (isRun) {
    Canvas c = null;
    try {
    synchronized (holder) {
    c = holder.lockCanvas();
    c.drawColor(Color.BLACK);
    Paint p = new Paint();
    p.setColor(Color.WHITE);
    Rect r = new Rect(100, 50, 300, 250);
    c.drawRect(r, p);
    c.drawText("这是第" + (count++) + "秒", 100, 310, p);
    Thread.sleep(1000);
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    if (c != null) {
    holder.unlockCanvasAndPost(c);
    }
    }
    }
    }
    }
    }

    注意事项

  • 线程安全:SurfaceView 的绘制操作应在 UI 线程或专用绘图线程中进行,确保与 SurfaceHolder 的同步操作协调一致。
  • 性能优化:合理使用 lockCanvas() 和 unlockCanvasAndPost() 方法,避免不必要的资源消耗。
  • 透明度管理:如果在 Surface 上放置透明控件,需确保回调机制能够及时更新,这可能对性能产生影响。
  • 通过以上方法,开发者可以充分利用 SurfaceView 的功能,实现高效、稳定的图形绘制和渲染效果。

    上一篇:Android--手机一键Root原理分析
    下一篇:Android--中国象棋

    发表评论

    最新留言

    网站不错 人气很旺了 加油
    [***.192.178.218]2025年04月27日 06时16分03秒