2

私のアクティビティには次のものがあります。

private Set<MediaPlayer> mediaPlayers;

public void onSomeEventInMyActivity()
{
    // play sound
    MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.my_sound);
    mediaPlayers.add(mediaPlayer);
    mediaPlayer.setOnCompletionListener(new OnCompletionListener()
    {
        @Override
        public void onCompletion(MediaPlayer mp)
        {
            mp.release();
            mediaPlayers.remove(mp);
        }
    });
    mediaPlayer.start();
}

@Override
protected void onStart()
{
    super.onStart();

    mediaPlayers = new HashSet<MediaPlayer>();
}

@Override
protected void onStop()
{
    super.onStop();

    for (MediaPlayer mediaPlayer : mediaPlayers)
    {
        if (mediaPlayer.isPlaying())
        {
            mediaPlayer.stop();
        }
        mediaPlayer.release();
    }
}

このコードは十分ですか、それとも MediaPlayer の漏洩につながりますか? onStopとの実装は必要ですか、それとも の呼び出しにonStart頼ることができますか?releaseonCompletion

onStop()MediaPlayer の再生中に呼び出される可能性があるため、この方法でコードを作成しました。まだ呼び出されないreleaseため、呼び出す必要があります。onCompletionあくまでも推測なので間違っていたらごめんなさい。

onStopまた、メモリ不足の状況では呼び出されないことも読みました-その後どうすればよいですか?

4

2 に答える 2

2

onStop()アクティビティが見えなくなったときに mediaPlayer が停止すると予想される場合は、ルーチンが必要です。それ以外の場合、mediaPlayer は再生を続けます。Gingerbread 以前の古い OS では、onPause()たとえば電話がかかってきたときにアクティビティが実行され、極端な状況では実行されることなく破棄されonStop()ます。その場合、実行中の mediaPlayer がどうなるかわかりません。ただし、電話がかかってきた場合は、mediaPlayer をonPause()!で停止することをお勧めします。onStop()その後の OS は、Activity を破棄する前に必ず通過します。またはmp.release()で停止した後に mediaPlayer を呼び出すことは正しいです。onPause()onStop()

で保持されているプレーヤーへの参照を削除することも望ましいですがmediaPlayers、これは上記の onStop() では発生しません。何かのようなもの:

    @Override public void onCompletion(MediaPlayer mp) {
        mp.stop();   // It's always safe to call stop()
        mp.release();  // release resources internal to the MediaPlayer
        mediaPlayers.remove(mp); // remove reference to MediaPlayer to allow GC
    }

その後

@Override public void onPause() {
     for (Object mediaPlayer : mediaPlayers.toArray()) {
          onCompletion((MediaPlayer) mediaPlayer); // stop, release, and free for GC, each mp.
     } 
     super.onPause();
}

(私はもともとfor (Object mediaPlayer : mediaPlayers) {}上記のコードを持っていましたが、omfeddf345mnof32nisd45fgoq2t は、セットを反復しながらセットを変更することになると指摘しました。訂正していただきありがとうございます!)

于 2012-11-30T10:00:37.327 に答える
0

呼び出されることが保証されているコールバックのみがonPause()であるため、状況によってはこのメディアプレーヤーがリークする可能性があります。アクティビティの一時停止でプレーヤーを停止することが受け入れられない場合は、サービスを使用し、特定のイベント(電話の着信など)を監視する必要があります

于 2012-11-30T10:03:03.317 に答える