2011-07-06 54 views
16

Android MediaPlayer的文檔顯示reset()調用沒有無效狀態:http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States(無效狀態列爲{}或「none」。)。IllegalStateException調用MediaPlayer.reset()

不過,我已經看到了IllegalStateException拋出同時呼籲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) 

是文檔不正確的?

+0

嗯,它看起來像我與其他學科混淆'MediaPlayer'。抱歉混淆。 :) – Wroclai

回答

19

很難說沒有看到您的代碼,但我認爲您可能調用release()後調用reset()?

文檔狀態

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.

您可以將有效的生命週期之外調用復位。

+10

是的,在release()之後調用reset()會拋出一個非法的狀態異常 –

8

我遇到了你的問題,Skyler。

你是對的。文檔顯示mediaPlayer.reset()沒有無效狀態,但這不是文檔中的第一個不準確的地方。

我注意到VALID狀態列表並沒有說「Any」;它列出除了兩個以外的每個特定狀態:準備和結束。

我嘗試過,但在MediaPlayer希望處於準備狀態(使用prepareAsync())時嘗試調用release()時,不會引發IllegalStateException。我不能保證它不會發生,但我無法做到這一點。我確實看到了該實例是以下日誌消息:

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

是,無論錯誤消息,一個右後外 - 一個用小寫的「錯誤」,一個大寫的「錯誤」,但沒有拋出異常。

但是,如果我在呼叫釋放後復位()(),然後我得到的錯誤:

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 

所以現代水墨的猜測是正確的。 MediaPlayer.reset()在End狀態(在調用release()後發生IllegalStateException)。在我的情況下,我發現我在onPause()上調用release(),但沒有在onResume()中再次初始化MediaPlayer。因此,當我調用reset()時它處於End狀態;

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.

這意味着你需要從頭再來創建的MediaPlayer,從媒體播放器=新的MediaPlayer()或的mediaPlayer.onCreate()方法中的一種。或者當你調用release()的時候要小心。

3

顯然,Android MediaPlayer的文檔對於reset()沒有無效狀態是不正確的。下面就是發生在我經歷過:我作爲MediaPlayer爲靜態,這樣我可以在我家activity使用它

在我PlayerActivity.java代碼:

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

在我家activity,我釋放了玩家在關閉應用程序之前:

​​

因此,當我第一次啓動應用程序並開始播放歌曲。 reset()函數運行良好,沒有錯誤。但是當我點擊後面button來關閉應用程序並第二次啓動時,IllegalStateException在通過reset()函數時發生。

我也在調試時發現了原因。作爲第一次運行應用程序,播放器爲空,因此它在onCreate()函數PlayerActivity.java中初始化。但該應用程序關閉後,該玩家不會將其自身釋放到null。所以第二次重新開放時不會重新初始化。這就是爲什麼IllegalStateException傳遞reset()函數時發生的原因。因此,要解決這個問題,我已經關閉應用程序之前給玩家設置爲null

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

} 
相關問題