我愿意接受建议。我正在编写一个应用程序,需要在应用程序的所有活动之间播放音乐,并在用户通过回击并退出应用程序来“回家”或“退出”应用程序时暂停。所以这就是我所做的 - 我创建了一个“SoundController”类,其中包含一个MediaPlayer的静态实例,如下所示:
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();
}
}
我在我的应用程序中对每个活动的“onResume()”和“onPause()”调用“.start()”和“.pause()”,如下所示:
@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();
}
}
但出于某种原因,我注意到了几个错误:
在我的应用程序被销毁之前,我的静态媒体播放器实体是否在某种程度上被破坏了?
如果音乐在我的应用程序退出后长时间播放,那么“_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
答案 0 :(得分:1)
您似乎没有使用服务,但它是此类的完美用例:允许在没有UI的情况下执行后台任务。播放音乐不需要UI(控制它需要一个当然)。 另外,使用
prepareAsync()
而不是prepare(),除非你将你的服务放在一个单独的线程中:prepare()是同步的,这意味着当媒体播放器正在启动歌曲时,你的主线程(你的UI所在的位置)将被阻止。
答案 1 :(得分:0)
好的,这里的关键是Kindle Fire& WarrenFaith对我的问题发表评论。
足够愚蠢,在Kindle Fire版本1上,活动周期有时会搞砸 - onPause在调用onDestroy后被调用。这没有道理。在我的onDestroy()中,我拆掉了整个SoundController变量,因为来自我的主要活动的onDestroy意味着用户“退出”我的应用程序。
所以发生的事情是媒体播放器死后onPause被调用。当然,到那时,它处于非法状态。
这个bug在我的其他两个Android设备上无法重现。 (真正的蓝色机器人,不是它的分叉版本,像点燃火灾)