2011-07-06 21 views
16

La documentación para Android MediaPlayer muestra que no hay estados no válidos para la llamada reset(): http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States (los estados no válidos se enumeran como {} o "ninguno").Llamada IllegalStateException MediaPlayer.reset()

Sin embargo, he visto un IllegalStateException arrojados al llamar reset():

java.lang.IllegalStateException 
at android.media.MediaPlayer._reset(Native Method) 
at android.media.MediaPlayer.reset(MediaPlayer.java:1061) 
at com.example.android.player.AsyncPlayer$AsyncHandler.handleMessage(AsyncPlayer.java:654) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:123) 
at android.os.HandlerThread.run(HandlerThread.java:60) 

es la documentación incorrecta?

+0

Hm, parecía que estaba confundiendo el 'MediaPlayer' con otro tema. Perdon por la confusion. :) – Wroclai

Respuesta

19

Es difícil de decir sin ver su código, pero creo que es posible que esté llamando a restablecer() después de llamar a la versión()?

La documentación indica

When a MediaPlayer object is just created using new or after reset() is called, it is in the Idle state; and after release() is called, it is in the End state. Between these two states is the life cycle of the MediaPlayer object.

Es posible que se llama reinicio fuera del ciclo de vida válido.

+10

Sí, al llamar a restablecer() después del lanzamiento() lanzará unaexcepción de estado ilegal –

8

Me encontré con su problema, Skyler.

Estás en la correcta. La documentación no muestra estados inválidos para mediaPlayer.reset(), pero esa no es la primera inexactitud en la documentación.

Lo que noté es que la lista de estados VÁLIDOS no dice "Cualquiera"; enumera cada estado específico excepto dos: preparación y finalización.

Experimenté, pero no pude causar que IllegalStateException se lanzara en mis intentos de llamar a release() mientras que el MediaPlayer está en el estado de Preparación (usando prepareAsync()). No garantizaré que no ocurra, pero no podría hacerlo realidad. Lo que hice notar en este ejemplo fueron los siguientes mensajes de registro:

04-11 11:41:54.740: E/MediaPlayer(4930): error (1, -2147483648) 
04-11 11:41:54.748: E/MediaPlayer(4930): Error (1,-2147483648) 

Sí, ambos aparecen mensajes de error, uno después del otro - uno con minúscula "error" y una con mayúscula "error", pero sin Se lanza una excepción.

Sin embargo, si llamo reset() después de la liberación(), entonces me sale el error:

04-11 11:45:05.232: E/AndroidRuntime(5046): FATAL EXCEPTION: main 
04-11 11:45:05.232: E/AndroidRuntime(5046): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.helloandroid/com.android.helloandroid.HelloAndroidActivity}: java.lang.RuntimeException: java.lang.IllegalStateException 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1696) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1716) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread.access$1500(ActivityThread.java:124) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:968) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.os.Looper.loop(Looper.java:123) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread.main(ActivityThread.java:3806) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at java.lang.reflect.Method.invoke(Method.java:507) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at dalvik.system.NativeStart.main(Native Method) 
04-11 11:45:05.232: E/AndroidRuntime(5046): Caused by: java.lang.RuntimeException: java.lang.IllegalStateException 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at com.android.helloandroid.HelloAndroidActivity.crashMediaPlayer(HelloAndroidActivity.java:423) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at com.android.helloandroid.HelloAndroidActivity.onCreate(HelloAndroidActivity.java:87) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1660) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  ... 11 more 
04-11 11:45:05.232: E/AndroidRuntime(5046): Caused by: java.lang.IllegalStateException 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.media.MediaPlayer._reset(Native Method) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at android.media.MediaPlayer.reset(MediaPlayer.java:1112) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  at com.android.helloandroid.HelloAndroidActivity.crashMediaPlayer(HelloAndroidActivity.java:421) 
04-11 11:45:05.232: E/AndroidRuntime(5046):  ... 14 more 

Así conjetura de la tinta moderna era correcta. MediaPlayer.reset() arroja IllegalStateException en el estado End (que ocurre después de que se llama a release()).

En mi caso, descubrí que estaba llamando a release() en onPause(), pero no hice nada para inicializar nuevamente MediaPlayer en onResume(). Por lo tanto, estaba en el estado Final cuando llamé a reset();

por http://developer.android.com/reference/android/media/MediaPlayer.html,

Once the MediaPlayer object is in the End state, it can no longer be used and there is no way to bring it back to any other state.

Eso significa que necesita para crear el MediaPlayer de nuevo, comenzando con MediaPlayer = new MediaPlayer() o uno de los métodos mediaPlayer.onCreate(). O tenga cuidado cuando llame al lanzamiento().

3

Aparentemente la documentación del Android MediaPlayer no es correcta sobre la no existencia de un estado no válido para reset().A continuación es lo que sucede cuando lo experimenté:

En mi código PlayerActivity.java, puse mis MediaPlayer como estático para que lo puedo usar en mi casa activity:

public class PlayerActivity extends Activity { 
.... 

public static MediaPlayer mp; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Mediaplayer 
    if(mp == null) { 
     mp = new MediaPlayer(); 
    } 
    .... 
} 
/** 
* Function to play a song 
* @param songIndex - index of song 
* */ 
public void playSong(int songIndex){ 
    // Play song 
    try { 
     if(mUpdateTimeTask != null) 
      mHandler.removeCallbacks(mUpdateTimeTask); 
     mp.reset(); 
      // the song path is get from internet 
    mp.setDataSource(songsList.get(songIndex).get("songPath")); 
    mp.prepareAsync(); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
... 
} 

En mi casa activity, libero el jugador antes de cerrar la aplicación:

public class TuoiTreAppActivity extends TabActivity { 
    ... 

    @Override 
    public void onDestroy(){ 
     if(PlayerActivity.mp != null) { 
     PlayerActivity.mp.release(); 
     } 
     super.onDestroy(); 

    } 
    ... 

} 

Por lo tanto, cuando lance la aplicación por primera vez y empiece a reproducir una canción. La función reset() funciona bien sin error. Pero cuando toco la parte posterior button para cerrar la aplicación y ejecutarla por segunda vez, aparece el IllegalStateException al pasar la función reset().

También descubrí la causa cuando se depura. Como la primera vez que ejecuta la aplicación, el reproductor es nulo, por lo que se inicializa en la función onCreate() de PlayerActivity.java. Pero el reproductor no se libera a sí mismo al null después de que se cerró la aplicación. Por lo tanto, no se inicializa de nuevo cuando vuelve a abrir por segunda vez. Esa es la razón por la cual IllegalStateException se produce al pasar la función reset(). Por lo tanto, para resolver este problema, tengo que configurar el reproductor para null antes de cerrar la aplicación:

@Override 
public void onDestroy(){ 
    if(PlayerActivity.mp != null) { 
     PlayerActivity.mp.release(); 
     // Set the MediaPlayer to null to avoid IlLegalStateException 
      // when call mp.reset() after launching the app again 
     PlayerActivity.mp = null; 
    } 

    super.onDestroy(); 

} 
Cuestiones relacionadas