当我尝试setDisplay到MediaPlayer的表面已被释放 [英] The surface has been released when I try to setDisplay to MediaPlayer

查看:3210
本文介绍了当我尝试setDisplay到MediaPlayer的表面已被释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的XML文件:

 < SurfaceView
    机器人:ID =@ + ID / surfaceView
    机器人:layout_marginTop =50dp
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =300dp/>
 

我的功能setDisplay:

 公共无效的playVideo(){
    MediaPlayer的熔点为新的MediaPlayer();
    SurfaceView SV =(SurfaceView)this.findViewById(R.id.surfaceView);
    尝试 {
        mp.setDataSource(SD卡/测试/ a.3gp);
        SurfaceHolder的sh = sv.getHolder();
        mp.setDisplay(SH); *** ----除了这里发生***
        MP prepare()。
        mp.start();
    }赶上(抛出:IllegalArgumentException E){
        e.printStackTrace();
    }赶上(SecurityException异常E){
        e.printStackTrace();
    }赶上(IllegalStateException异常E){
        e.printStackTrace();
    }赶上(IOException异常E){
        e.printStackTrace();
    }
}
 

如下的记录:

  04-24 22:19:33.645:W / System.err的(16106):java.lang.IllegalArgumentException:如果表面已被释放
04-24 22:19:33.645:W / System.err的(16106):在android.media.MediaPlayer._setVideoSurface(本机方法)
04-24 22:19:33.645:W / System.err的(16106):在android.media.MediaPlayer.setDisplay(MediaPlayer.java:698)
 

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

解决方案

表面可摧毁。这就是为什么你需要添加到一个公共无效surfaceDestroyed(SurfaceHolder持有人)您SurfaceView的实现是这样的:

  @覆盖
公共无效surfaceDestroyed(SurfaceHolder持有者){
    同步(本){
        hasActiveHolder = FALSE;

        同步(本){
              this.notifyAll();
        }
    }
}
 

您应该还添加了一个函数处理曲面创建:

  @覆盖
公共无效surfaceCreated(SurfaceHolder持有者){
     同步(本){
        hasActiveHolder = TRUE;
        this.notifyAll()
     }
}
 

和修改自己的功能是这样的:

  mp.setDataSource(SD卡/测试/ a.3gp);
    SurfaceHolder的sh = sv.getHolder();
    同步(本){
       而(!hasActiveHolder){
              尝试 {
                  this.wait();
              }赶上(InterruptedException异常E){
                //打印的东西
              }
        }
        mp.setDisplay(SH);
        MP prepare()。
    }
 

您有另一种选择是对的方式谷歌建议您使用SurfaceView:在一个单独的线程

My xml file:

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

My function to 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();
    }
}

the log as below:

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)

I have found some similar questions here, but all of those are not suit for me. Waiting for your answers. Thanks very much.

解决方案

The Surface can be destroyed. That's why you need to add to the a public void surfaceDestroyed(SurfaceHolder holder) to your SurfaceView's implementation like this:

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

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

You should also add a function that handles Surface creation:

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

And modify your own function this way:

    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();
    }

You have another option which is the way Google suggests you use SurfaceView: in a separate thread.

这篇关于当我尝试setDisplay到MediaPlayer的表面已被释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆