android - 当我尝试将显示设置为 MediaPlayer 时,表面已被释放

标签 android surfaceview android-mediaplayer

我的 xml 文件:

<SurfaceView
    android:id="@+id/surfaceView"
    android:layout_marginTop="50dp"
    android:layout_width="fill_parent"
    android:layout_height="300dp" />

我的 setDisplay 函数:

public void playVideo() {
    MediaPlayer mp = new MediaPlayer();
    SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView);
    try {
        mp.setDataSource("sdcard/test/a.3gp");
        SurfaceHolder sh = sv.getHolder();
        mp.setDisplay(sh);***----the exception occured here***
        mp.prepare();
        mp.start();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

日志如下:

04-24 22:19:33.645: W/System.err(16106): java.lang.IllegalArgumentException: The surface has been released
04-24 22:19:33.645: W/System.err(16106):    at android.media.MediaPlayer._setVideoSurface(Native Method)
04-24 22:19:33.645: W/System.err(16106):    at android.media.MediaPlayer.setDisplay(MediaPlayer.java:698)

我在这里发现了一些类似的问题,但所有这些问题都不适合我。等待您的答复。非常感谢。

最佳答案

表面可以被破坏。这就是为什么您需要将 public void surfaceDestroyed(SurfaceHolder holder) 添加到 SurfaceView 的实现中,如下所示:

  @Override
public void surfaceDestroyed(SurfaceHolder holder) {
    synchronized (this) {
        hasActiveHolder = false;

        synchronized(this)          {
              this.notifyAll(); 
        }
    } 
}

您还应该添加一个处理 Surface 创建的函数:

@Override
public void surfaceCreated(SurfaceHolder holder) {
     synchronized (this) {
        hasActiveHolder = true;
        this.notifyAll()
     }
}

然后这样修改你自己的函数:

    mp.setDataSource("sdcard/test/a.3gp");
    SurfaceHolder sh = sv.getHolder();
    synchronized (this) {
       while (!hasActiveHolder) {
              try {
                  this.wait();
              } catch (InterruptedException e) {
                //Print something
              }
        }
        mp.setDisplay(sh);
        mp.prepare();
    }

您还有另一种选择,即 Google 建议您使用 SurfaceView 的方式:在单独的线程中。

关于android - 当我尝试将显示设置为 MediaPlayer 时,表面已被释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16194941/

相关文章:

android - 从 SQLite DB 中获取图像并在 WebView 中显示它们的最佳方法 (Android)

android - 自定义操作栏的最佳方式

android - 在网格布局中并排调整和缩放两个图像

java - 从另一个 Activity 停止/启动媒体播放器

android - 如何以设定的时间间隔循环播放不同次数的声音-Android

android - 如何在android studio中设置库

android - 我如何关闭/退出我的应用程序上的按钮?

android - 截取常规View和SurfaceView的复合屏幕 View

android - 提高 SurfaceView 派生的自定义 View 的性能?

android - 如何使扩展 SurfaceView 的类启动 Activity?