Поверхность была выпущена, когда я пытаюсь установить Disisplay на 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) 

Здесь я нашел несколько подобных вопросов, но все они не подходят для меня. Жду ваших ответов. Огромное спасибо.

Solutions Collecting From Web of "Поверхность была выпущена, когда я пытаюсь установить Disisplay на MediaPlayer"

Поверхность может быть уничтожена. Вот почему вам необходимо добавить к public void surfaceDestroyed(SurfaceHolder holder) для реализации SurfaceView следующим образом:

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

Вы также должны добавить функцию, которая обрабатывает создание поверхности:

 @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: в отдельном потоке.

Это связано с последовательностью выполнения, так как поверхность должна быть создана сначала перед установкой отображения для MediaPlayer, so you have to override the callback method surfaceCreated` следующим образом:

 @Override public void surfaceCreated(SurfaceHolder holder) { mp.setDisplay(sh); // now "mp" is defined as a class variable } 

И теперь нет необходимости устанавливать параметр в вашем игровом методе:

 private MediaPlayer mp; // to use it inside surfaceCreated callback method public void playVideo() { mp = new MediaPlayer(); SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView); try { mp.setDataSource("sdcard/test/a.3gp"); SurfaceHolder sh = sv.getHolder(); mp.prepare(); mp.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 

Самый простой способ – просто вызвать setDisplay в surfaceCreated :

 @Override public void surfaceCreated(SurfaceHolder holder) { mp.setDisplay(holder) } 

И не забудьте отвязать поверхность:

 @Override public void surfaceDestroyed(SurfaceHolder holder) { mp.setDisplay(null); } 

Примечание. Медиа-плеер должен быть инициализирован где-то раньше, например, в onCreate .

Для тех, у кого по-прежнему возникают проблемы, попробуйте выполнить SurfaceHolder.Callback в вашей деятельности / фрагменте / etc и в методе onCreate / onCreateView , вызовите метод обратного вызова addCallback (SurfaceHolder.Callback) , используя вашу активность / фрагмент / etc в качестве обратного вызова параметра.

Используйте SurfaceHolder.Callback, как показано ниже

 SurfaceView mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); SurfaceHolder holder = mSurfaceView.getHolder(); final MediaPlayer player = new MediaPlayer(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { player.setDisplay(holder); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); String UrlPath="android.resource://"+getActivity().getPackageName()+"/"+R.raw.your_file_name_without_extension; try { player.setDataSource(getActivity(),Uri.parse(UrlPath)); player.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } });