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 泄漏?我的实现是必要的onStoponStart还是只能依靠调用?releaseonCompletion

我这样做是因为我假设onStop()可以在 MediaPlayer 播放时调用我的代码,所以我需要调用release因为onCompletion还不会被调用。我只是猜测这是对的,如果我错了,请纠正我。

我还读到了onStop在内存不足的情况下不调用的内容-那该怎么办?

4

2 回答 2

2

onStop()如果 mediaPlayer 预计在活动变得不可见时停止,则需要一个例程。否则, mediaPlayer 会继续播放。在较旧的操作系统、Gingerbread 和更早的版本上,活动可以执行onPause()——比如,当一个电话到来时——并且在极端情况下,可以在不执行的情况下被销毁onStop()。我不知道正在运行的 mediaPlayer 会发生什么。但是,如果有电话打进来,最好停止 mediaPlayer onPause()!后来的操作系统总是onStop()在销毁 Activity 之前通过。在停止 mediaPlayer 之后调用mp.release()它,无论是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 回答