如何应对Android SurfaceView中的SurfaceChanged事件

作者:嘉兴麻将开发公司 阅读:34 次 发布时间:2023-05-13 06:38:08

摘要:Android开发中,SurfaceView是一种特殊的View类型,可以用于实时的图像或视频展示。它的独特之处在于可以在一个独立的线程中处理渲染,因此可以避免在UI线程中进行繁琐的渲染操作,从而提高了应用的性能和流畅度。在SurfaceView中,有一个非常重要的事件叫做SurfaceChanged。...

Android开发中,SurfaceView是一种特殊的View类型,可以用于实时的图像或视频展示。它的独特之处在于可以在一个独立的线程中处理渲染,因此可以避免在UI线程中进行繁琐的渲染操作,从而提高了应用的性能和流畅度。

如何应对Android SurfaceView中的SurfaceChanged事件

在SurfaceView中,有一个非常重要的事件叫做SurfaceChanged。它在Surface创建/改变时被调用,因此通常用来在SurfaceView中进行初始化操作,比如设置Surface的尺寸、格式等等。但是,由于SurfaceChanged事件的特殊性,它也会带来一些开发中的难点。下面我们就来探讨一下如何应对Android SurfaceView中的SurfaceChanged事件。

一、理解SurfaceChanged事件

在SurfaceView中,SurfaceChanged事件是一种比较基础的事件,它主要是在Surface创建或改变时被触发。在Android开发中,我们通常会使用SurfaceHolder接口来管理SurfaceView中的Surface对象。SurfaceHolder接口提供了三个回调方法来响应Surface的生命周期:

1. surfaceCreated(SurfaceHolder holder) - Surface被创建时调用

2. surfaceChanged(SurfaceHolder holder, int format, int width, int height) - Surface尺寸、格式等属性改变时调用

3. surfaceDestroyed(SurfaceHolder holder) - Surface被销毁时调用

其中,surfaceChanged方法是我们要重点关注的事件,因为它提供了Surface的尺寸、格式等信息,可以在这里进行一些初始化设置。具体来说,SurfaceChanged事件包含了以下参数:

1. holder - SurfaceHolder对象,用于管理Surface

2. format - Surface的像素格式,比如PixelFormat.RGBA_8888等

3. width - Surface的宽度

4. height - Surface的高度

这些信息对于SurfaceView的渲染和显示都非常重要,因此在处理SurfaceChanged事件时要特别注意。

二、如何应对SurfaceChanged事件

在处理SurfaceChanged事件时,我们通常需要开启一个独立的线程用于进行渲染操作。这是因为在UI线程中进行渲染会影响界面的流畅度和响应速度,尤其是在渲染大量图形或视频时。在独立线程中进行渲染,可以避免主线程卡顿,提高应用性能。

那么在独立线程中如何应对SurfaceChanged事件呢?一般来说,我们需要在SurfaceCreated事件中创建线程,并在SurfaceChanged事件中更新线程所需的参数。具体流程如下:

1. 在SurfaceCreated事件中创建渲染线程,并将SurfaceHolder对象传给该线程用于渲染。

2. 在SurfaceChanged事件中更新渲染线程所需的Surface参数,比如宽度、高度等。

3. 在渲染线程中进行渲染操作,渲染结果发送至SurfaceView中进行显示。

下面我们就以一个简单的例子来说明如何应对SurfaceChanged事件。

1. 创建渲染线程

在SurfaceCreated事件中,我们需要创建一个独立的线程用于进行渲染操作。如下所示:

```

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

private RenderThread mRenderThread;

public void surfaceCreated(SurfaceHolder holder) {

// 创建渲染线程

mRenderThread = new RenderThread(holder);

mRenderThread.start();

}

//...

}

class RenderThread extends Thread {

private SurfaceHolder mHolder;

public RenderThread(SurfaceHolder holder) {

mHolder = holder;

}

@Override

public void run() {

// 在该线程中进行渲染

while (!interrupted()) {

Canvas canvas = mHolder.lockCanvas();

if (canvas != null) {

// 渲染操作

mHolder.unlockCanvasAndPost(canvas);

}

}

}

}

```

这里创建了一个RenderThread线程用于进行渲染操作,同时将SurfaceHolder对象传给该线程用于渲染。

2. 更新渲染参数

在SurfaceChanged事件中,我们需要更新渲染线程所需的参数,比如宽度、高度等。如下所示:

```

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

// 更新渲染线程所需的参数

mRenderThread.updateSurfaceSize(width, height);

}

```

这里调用了RenderThread中的updateSurfaceSize方法,用于更新渲染线程所需的Surface尺寸信息。

```

class RenderThread extends Thread {

private SurfaceHolder mHolder;

private int mWidth;

private int mHeight;

public RenderThread(SurfaceHolder holder) {

mHolder = holder;

}

// 更新Surface尺寸信息

public void updateSurfaceSize(int width, int height) {

mWidth = width;

mHeight = height;

}

@Override

public void run() {

// 在该线程中进行渲染

while (!interrupted()) {

Canvas canvas = mHolder.lockCanvas();

if (canvas != null) {

// 更新Canvas尺寸

canvas.drawColor(Color.WHITE);

// 渲染操作

mHolder.unlockCanvasAndPost(canvas);

}

}

}

}

```

这里在RenderThread中新增了一个updateSurfaceSize方法,用于更新Surface尺寸信息。同时,在渲染操作中也需要更新Canvas的尺寸信息。

3. 进行渲染操作

在RenderThread中进行渲染操作,然后将渲染结果发送到SurfaceView中进行显示。如下所示:

```

class RenderThread extends Thread {

//...

private Paint mPaint = new Paint();

@Override

public void run() {

// 在该线程中进行渲染

while (!interrupted()) {

Canvas canvas = mHolder.lockCanvas();

if (canvas != null) {

// 更新Canvas尺寸

canvas.drawColor(Color.WHITE);

// 渲染操作

mPaint.setColor(Color.RED);

canvas.drawCircle(mWidth/2f, mHeight/2f, mWidth/4f, mPaint);

// 将渲染结果发送到SurfaceView中进行显示

mHolder.unlockCanvasAndPost(canvas);

}

}

}

}

```

这里在RenderThread中进行了简单的渲染操作,然后将渲染结果发送到SurfaceView中进行显示。需要注意的是,在SurfaceCreated事件中创建渲染线程时,要设置线程的运行状态为正在运行:

```

public void surfaceCreated(SurfaceHolder holder) {

// 创建渲染线程

mRenderThread = new RenderThread(holder);

mRenderThread.setRunning(true); // 设置线程为正在运行状态

mRenderThread.start();

}

class RenderThread extends Thread {

private SurfaceHolder mHolder;

private volatile boolean mRunning; // 线程运行状态标记

public RenderThread(SurfaceHolder holder) {

mHolder = holder;

}

public void setRunning(boolean running) {

mRunning = running;

}

//...

}

```

这样,在SurfaceView销毁时,可以通过设置线程的状态为停止来终止渲染线程的运行:

```

public void surfaceDestroyed(SurfaceHolder holder) {

// 停止渲染线程

boolean retry = true;

mRenderThread.setRunning(false); // 设置线程为停止状态

while (retry) {

try {

mRenderThread.join();

retry = false;

} catch (InterruptedException e) {

// do nothing

}

}

mRenderThread = null;

}

```

三、总结

在SurfaceView中,SurfaceChanged事件是一种比较基础的事件,它提供了Surface的尺寸、格式等信息,可以在这里进行一些初始化设置。在处理SurfaceChanged事件时,我们通常需要开启一个独立的线程用于进行渲染操作,并在SurfaceCreated事件中创建渲染线程,同时在SurfaceChanged事件中更新渲染线程所需的参数。在渲染线程中进行渲染操作,然后将渲染结果发送到SurfaceView中进行显示。在SurfaceView销毁时,需要通过设置线程的状态为停止来终止渲染线程的运行,从而避免线程的不必要运行和资源浪费。

  • 原标题:如何应对Android SurfaceView中的SurfaceChanged事件

  • 本文链接:https:////zxzx/7485.html

  • 本文由深圳飞扬众网小编,整理排版发布,转载请注明出处。部分文章图片来源于网络,如有侵权,请与飞扬众网联系删除。
  • 微信二维码

    CTAPP999

    长按复制微信号,添加好友

    微信联系

    在线咨询

    点击这里给我发消息QQ客服专员


    点击这里给我发消息电话客服专员


    在线咨询

    免费通话


    24h咨询☎️:166-2096-5058


    🔺🔺 棋牌游戏开发24H咨询电话 🔺🔺

    免费通话
    返回顶部