【问题标题】:why does a static MediaPlayer instance not work for Android?为什么静态 MediaPlayer 实例不适用于 Android?
【发布时间】:2012-09-12 09:15:50
【问题描述】:

我愿意接受建议。我正在编写一个应用程序,该应用程序需要在应用程序的所有活动之间播放音乐,并在用户点击“主页”或通过回击并退出我的应用程序时“退出”应用程序时暂停。所以这就是我所做的 - 我创建了一个包含 MediaPlayer 静态实例的“SoundController”类,如下所示:

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

但由于某种原因,我注意到一些错误,例如:

  • 即使在应用程序退出后,音乐也会继续播放,如果我做的事情足够快,比如我启动应用程序,很快就回家,然后再次启动应用程序,然后按“返回”键退出应用程序...
  • 应用程序在尝试退出时崩溃,因为出于某种原因,onPause() 会在 onDestroy() 之后被调用...。请有人告诉我,我什至不知道这是可能的。 (我将它记录在我的 logcat 中,在 kindle fire 上)

是不是我的媒体播放器的静态实例在我的应用程序被销毁之前就以某种方式被破坏了?

如果我的应用退出后音乐一直播放很久,是不是“_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

【问题讨论】:

  • logging it in my logcat 永远不要相信你的日志顺序......还有app crashes 那次崩溃的堆栈跟踪在哪里?
  • 对于这种后台任务,您绝对应该使用Service(参见SDK 中的RandomMusicPlayer 示例项目)
  • @WarrenFaith 等等... logcat 的排序不准确?但打印线是时间戳!那我可以依靠什么?
  • @fiddler 好的,我得看看那个。感谢您的建议
  • @WarrenFaith 哦,应用程序崩溃了:{if(_musicPlayer.isPlaying())} in pauseMusic()

标签: android audio android-activity static media-player


【解决方案1】:

您似乎没有使用服务,但它是此类的完美用例:允许在没有 UI 的情况下执行后台任务。播放音乐不需要 UI(控制它当然需要一个)。 另外,使用

prepareAsync()

而不是 prepare() 除非您将 Service 放在单独的线程中:prepare() 是同步的,这意味着当媒体播放器开始播放歌曲时,您的主线程(您的 UI 所在的位置)将被阻塞。

【讨论】:

  • 我会给你一个 +1 的建议,prepareAsync 似乎是一个更好的选择。
【解决方案2】:

好的,这里的关键是 Kindle Fire 和 WarrenFaith 对我的问题的评论。

很愚蠢,在 Kindle Fire 版本 1 上,活动周期有时会搞砸 - 在调用 onDestroy 之后调用 onPause。这没有道理。在我的 onDestroy() 中,我拆除了整个 SoundController 变量,因为我的主要活动中的 onDestroy 意味着用户“退出”了我的应用程序。

所以发生的事情是 onPause 在媒体播放器死后被调用。当然,到那时,它处于非法状态。

这个错误在我的另外两台安卓设备上无法重现。 (真正的蓝色 android,不是它的分叉版本,就像 kindle fire)

【讨论】:

    猜你喜欢
    • 2020-05-23
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多