2011-07-06 21 views
16

Tài liệu dành cho Android MediaPlayer cho thấy rằng không có trạng thái không hợp lệ cho cuộc gọi reset(): http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States (trạng thái không hợp lệ được liệt kê là {} hoặc "không có").Gọi điện IllegalStateException MediaPlayer.reset()

Tuy nhiên, tôi đã thấy một IllegalStateException ném khi gọi 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) 

là các tài liệu không chính xác?

+0

Hm, nó trông giống như tôi đã nhầm lẫn giữa 'MediaPlayer' với chủ đề khác. Xin lỗi về sự nhầm lẫn. :) – Wroclai

Trả lời

19

Khó nói mà không nhìn thấy mã của bạn nhưng tôi nghĩ bạn có thể đang gọi lại đặt lại() sau khi bạn gọi bản phát hành()?

Các tài liệu khẳng định

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.

Bạn có thể được gọi thiết lập lại bên ngoài của vòng đời hợp lệ.

+10

Có, gọi lại đặt lại() sau khi phát hành() sẽ ném một ngoại lệ bất hợp pháp –

8

Tôi gặp phải sự cố của bạn, Skyler.

Bạn là chính xác. Tài liệu cho thấy không có trạng thái không hợp lệ cho mediaPlayer.reset(), nhưng đó không phải là sự thiếu chính xác đầu tiên trong tài liệu.

Điều tôi nhận thấy là danh sách các trạng thái VALID không nói "Bất kỳ"; nó liệt kê mọi trạng thái cụ thể ngoại trừ hai: Chuẩn bị và Kết thúc.

Tôi đã thử nghiệm, nhưng không thể khiến IllegalStateException bị ném trong nỗ lực gọi phát hành() trong khi MediaPlayer hy vọng ở trạng thái Chuẩn bị (sử dụng preparAsync()). Tôi sẽ không đảm bảo nó không xảy ra, nhưng tôi không thể làm cho nó xảy ra. Những gì tôi đã thấy trong trường hợp đó là các thông điệp tường trình sau đây:

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

Có, cả hai thông báo lỗi xuất hiện Ngoại lệ được ném.

Tuy nhiên, nếu tôi gọi reset() sau khi phát hành() sau đó tôi nhận được lỗi:

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 

Vì vậy, đoán The Ink của Modern là đúng. MediaPlayer.reset() ném IllegalStateException trong trạng thái End (xảy ra sau khi release() được gọi).

Trong trường hợp của mình, tôi phát hiện ra mình đang gọi release() on onause(), nhưng không làm gì để khởi tạo lại MediaPlayer trong onResume(). Do đó, nó đã ở trạng thái End khi tôi gọi reset();

mỗi 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.

Điều đó có nghĩa bạn cần để tạo ra các MediaPlayer khắp nơi trên một lần nữa, bắt đầu với MediaPlayer = MediaPlayer mới() hoặc một trong các phương pháp mediaPlayer.onCreate(). Hoặc hãy cẩn thận khi bạn gọi phát hành().

3

Rõ ràng tài liệu dành cho Android MediaPlayer không đúng về trạng thái không hợp lệ cho reset().Dưới đây là những gì xảy ra khi tôi đã trải qua nó:

Trong mã PlayerActivity.java của tôi, tôi đặt MediaPlayer tôi như tĩnh để tôi có thể sử dụng nó trong nhà của tôi 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(); 
    } 
} 
... 
} 

Trong nhà tôi activity, tôi thả người chơi trước khi đóng ứng dụng:

public class TuoiTreAppActivity extends TabActivity { 
    ... 

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

    } 
    ... 

} 

Vì vậy, khi tôi khởi chạy ứng dụng lần đầu tiên và bắt đầu phát một bài hát. Chức năng reset() chạy tốt mà không có lỗi. Nhưng khi tôi nhấn lại button để đóng ứng dụng và khởi chạy ứng dụng lần thứ hai, thì IllegalStateException xảy ra khi chuyển chức năng reset().

Tôi cũng phát hiện ra nguyên nhân khi gỡ lỗi. Lần đầu tiên chạy ứng dụng, trình phát là null nên nó được khởi tạo ở hàm onCreate() của PlayerActivity.java. Tuy nhiên, người chơi không tự giải phóng thành null sau khi ứng dụng bị đóng. Vì vậy, nó không được khởi tạo lại khi mở lại lần thứ hai. Đó là lý do tại sao IllegalStateException xảy ra khi vượt qua chức năng reset(). Vì vậy, để giải quyết vấn đề này, tôi phải đặt người chơi null trước khi đóng ứng dụng:

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

} 
Các vấn đề liên quan