La superficie se ha liberado cuando intento setDisplay to MediaPlayer

Mi archivo xml:

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

Mi función de 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(); } } 

El registro como abajo:

 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) 

He encontrado algunas preguntas similares aquí, pero todas esas no son traje para mí. Esperando sus respuestas. Muchas gracias.

5 Solutions collect form web for “La superficie se ha liberado cuando intento setDisplay to MediaPlayer”

La Superficie puede ser destruida. Es por eso que usted necesita para añadir a la public void surfaceDestroyed(SurfaceHolder holder) un public void surfaceDestroyed(SurfaceHolder holder) a la aplicación de su SurfaceView de esta manera:

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

También debe agregar una función que maneje la creación de superficie:

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

Y modifique su propia función de esta manera:

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

Tienes otra opción que es la forma en que Google sugiere que uses SurfaceView: en un hilo separado.

Es algo relacionado con la secuencia de ejecución, ya que la superficie tiene que ser creada primero antes de configurar la visualización para el MediaPlayer, so you have to override the callback method surfaceCreated` a lo siguiente:

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

Y ahora no hay necesidad de setDisplay dentro de su método de juego:

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

La forma más sencilla es simplemente llamar a setDisplay en surfaceCreated :

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

Y no se olvide de desatar la superficie:

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

Nota: el reproductor multimedia debe inicializarse en alguna parte antes, por ejemplo en onCreate .

Para aquellos que siguen teniendo problemas, intente implementar SurfaceHolder.Callback en su activity / fragment / etc y en el método onCreate / onCreateView , llame al método addCallback (SurfaceHolder.Callback callback) , usando su activity / fragment / etc como el parámetro callback.

Hacer uso de SurfaceHolder.Callback como a continuación

 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(); } }); 
  • Analizar y reproducir un archivo .pls en Android
  • MediaPlayer / VideoView - Stream de una URL y luego guardar el video después de la caché?
  • Android Socket problema en Samsung Galaxy S4 (SGS4)
  • Transmisión de archivos de audio y almacenamiento en caché
  • ¿Cómo evitar que el exoplayer se recargue en caso de retroceso?
  • Cómo obtener datos de MediaStore.File y MediaStore.File.FileColumn
  • ¿Por qué se tarda más tiempo en que algunas corrientes de audio en Internet comiencen a reproducirse en un Samsung S3?
  • Android mediaPlayer - ¿hay un método "isPrepared ()" o "getStatus ()"?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.