2012-09-12 191 views
1

我願意接受建議。我正在編寫一個應用程序,需要在應用程序的所有活動之間播放音樂,並在用戶點擊「主頁」或「退出」應用程序時通過點擊並退出應用程序暫停。所以這裏就是我所做的 - 我犯了一個「SoundController」類,它包含的MediaPlayer的靜態實例,就像這樣:爲什麼靜態MediaPlayer實例不適用於Android?

private static MediaPlayer _musicPlayer; 
public static void init(Context ctx){ 
    _musicPlayer = new MediaPlayer(); 
    AssetFileDescriptor descriptor; 
    try { 
     descriptor = ctx.getAssets().openFd("something.ogg"); 
     _musicPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength()); 
     _musicPlayer.prepare(); 
     _musicPlayer.setLooping(true); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } 
} 

和我稱之爲「開始()」和「.pause()」在每個活動的「的onResume()」 和 「的onPause()」 在我的應用程序是這樣的:

@Override 
public void onResume(){ 
    System.out.println("got in onResume for mainActivity"); 
    SoundController.playMusic(); 
    super.onResume(); 
} 

@Override 
public void onPause(){ 
    System.out.println("got in onPause for mainActivity"); 
    SoundController.pauseMusic(); 
    super.onPause(); 
} 

@Override 
public void onDestroy(){ 
    System.out.println("got in onDestroy for mainActivity"); 
    SoundController.tearDown(); 
    super.onDestroy(); 
} 

其中SoundController方法是這樣的:

public static void playMusic(){ 
    if(!_musicPlayer.isPlaying()){ 
     _musicPlayer.start(); 
    } 
} 

public static void pauseMusic(){ 
    if(_musicPlayer.isPlaying()){ 
     _musicPlayer.pause(); 
    } 
} 

public static void tearDown(){ 
    if(_musicPlayer.isPlaying()){ 
     _musicPlayer.stop(); 
     _musicPlayer.release(); 
    } 
} 

但出於某種原因,我注意到一些錯誤,如:

  • 即使應用程序退出後,音樂仍會繼續播放,如果我做的事情足夠快,就像我啓動應用程序,真的很快打開家,然後再次啓動應用程序,然後點擊「返回」鍵退出應用程序。 ..
  • 應用程序崩潰時,試圖退出,因爲某些原因,onPause()被稱爲AFTER onDestroy()....有人請給我啓發這一點,我甚至不知道這是可能的。 (我記錄在我的logcat,在kindle火上)

是我的媒體播放器的靜態實例在我的應用程序被銷燬之前以某種方式銷燬嗎?

在我的應用程序退出後音樂持續播放很久的情況下,是否「_mediaPlayer.start()」具有延遲的開始,因此它通過檢查應用程序何時退出?

對於長篇文章感到抱歉。非常感謝!!!

============================================== =========

編輯這裏的日誌崩潰:

09-12 14:44:06.304: I/System.out(12191): got in onPause for mainActivity 
09-12 14:44:06.366: I/System.out(12191): got in onResume for mainActivity 
09-12 14:44:06.726: I/System.out(12191): got in onDestroy for mainActivity 
09-12 14:44:07.499: I/System.out(12191): got in onPause for mainActivity 
09-12 14:44:07.507: D/AndroidRuntime(12191): Shutting down VM 
09-12 14:44:07.507: W/dalvikvm(12191): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
09-12 14:44:07.507: E/AndroidRuntime(12191): FATAL EXCEPTION: main 
09-12 14:44:07.507: E/AndroidRuntime(12191): java.lang.RuntimeException: Unable to pause activity {com.blah/com.blah.mainActivity}: java.lang.IllegalStateException 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2354) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:2291) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.access$1700(ActivityThread.java:117) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:942) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.os.Handler.dispatchMessage(Handler.java:99) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.os.Looper.loop(Looper.java:130) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.main(ActivityThread.java:3683) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at java.lang.reflect.Method.invokeNative(Native Method) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at java.lang.reflect.Method.invoke(Method.java:507) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:850) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at dalvik.system.NativeStart.main(Native Method) 
09-12 14:44:07.507: E/AndroidRuntime(12191): Caused by: java.lang.IllegalStateException 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.media.MediaPlayer.isPlaying(Native Method) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at com.blah.controllers.SoundController.pauseMusic(SoundController.java:63) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at com.blah.mainActivity.onPause(mainActivity.java:53) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.Activity.performPause(Activity.java:3887) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1191) 
09-12 14:44:07.507: E/AndroidRuntime(12191): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2341) 
09-12 14:44:07.507: E/AndroidRuntime(12191): ... 12 more 
+1

'記錄在我的logcat'永遠不要相信你的日誌的順序......還有'應用程序崩潰'那崩潰的堆棧軌跡在哪裏? – WarrenFaith

+1

你絕對應該使用'Service'來處理這種後臺任務(請參閱SDK中的RandomMusicPlayer示例項目) – fiddler

+0

@WarrenFaith等待... logcat的排序不準確?但印刷線路已加蓋時間!所以我可以依靠什麼? –

回答

0

好的,這裏的關鍵是Kindle Fire & WarrenFaith對我的問題的評論。

足夠愚蠢的是,在Kindle Fire版本1上,活動週期有時會混亂 - 在調用onDestroy之後調用onPause。這個不成立。在我的onDestroy()中,我拆掉了整個SoundController變量,因爲我的主要活動中的onDestroy意味着用戶「退出」了我的應用程序。

所以發生的事情是onPause在媒體播放器死機後被調用。當然,那時它處於非法狀態。

這個bug在我的另外兩個android設備上是不可重現的。 (真正的藍色機器人,不是它的分叉版本,像點燃火)

1

你似乎沒有使用服務是,但它是一個完美的使用情況下,這個類:允許在沒有UI的情況下執行後臺任務。播放音樂不需要UI(控制它當然需要)。 此外,使用

prepareAsync()

,而不是準備(),除非你把你的服務在一個單獨的線程:準備()是同步的,這意味着你的主線程(在您的UI )將在媒體播放器開始播放歌曲時被阻止。

+0

後得到調用,我會給你一個建議的+1,prepareAsync似乎是一個更好的選擇。 –

相關問題