1

私は提案を受け入れています。私は、アプリのすべてのアクティビティ間で音楽を再生する必要があるアプリを作成しています。ユーザーが「ホーム」を押すか、アプリを押して終了することでアプリを「終了」すると一時停止します。これが私がしたことです-私は次のように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に、kindlefireで記録しています)

メディアプレーヤーの静的インスタンスが、アプリが破棄される前に何らかの理由で破棄されているということですか?

アプリが終了した後も音楽が長く再生され続ける場合、「_ 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
4

2 に答える 2

1

サービスを使用していないようですが、このクラスの完璧なユースケースです。UIなしでバックグラウンドタスクを実行できます。音楽の再生にはUIは必要ありません(もちろん、音楽の制御にはUIが必要です)。また、使用

prepareAsync()

サービスを別のスレッドに配置しない限り、prepare()の代わりに:prepare()が同期されます。これは、メディアプレーヤーが曲を開始している間、メインスレッド(UIがある場所)がブロックされることを意味します。

于 2012-09-12T09:34:08.133 に答える
0

さて、ここで重要なのは、私の質問に対するKindle Fire&WarrenFaithのコメントでした。

愚かなことに、Kindle Fireバージョン1では、アクティビティサイクルが混乱することがあります。onDestroyが呼び出された後にonPauseが呼び出されます。意味がない。onDestroy()では、メインアクティビティからのonDestroyはユーザーがアプリを「終了」したことを意味するため、SoundController変数全体を破棄します。

つまり、メディアプレーヤーが停止した後に、onPauseが呼び出されるということです。もちろん、その時までに、それは違法な状態にあります。

このバグは、他の2つのAndroidデバイスでは再現できません。(真っ青なアンドロイド、キンドルファイアのようなフォークバージョンではありません)

于 2012-10-12T02:45:18.773 に答える