当我尝试setDisplay到MediaPlayer的表面已被释放已被、当我、表面、MediaPlayer

由网友(我不戴套i.)分享简介:我的XML文件:< SurfaceView机器人:ID =@ + ID / surfaceView机器人:layout_marginTop =50dp机器人:layout_width =FILL_PARENT机器人:layout_height =300dp/>我的功能setDisplay:公共无效的play...

我的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)
 
android multimedia框架总结,Android Multimedia框架总结 三 MediaPlayer中创建到setDataSource过程...

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

解决方案

表面可摧毁。这就是为什么你需要添加到一个公共无效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.

阅读全文

相关推荐

最新文章