Android MediaPlayer.OnCompletionListener()的意外行为

时间:2015-01-27 19:26:58

标签: java android

我遇到了Android MediaPlayer.OnCompletionListener()的行为,我无法解释,我希望有人可以向我解释。

我已经实现了一个实用程序类,它负责我的应用程序中MediaManager的所有处理。用例是我创建并准备了MediaPlayer对象,一旦完成回放,MediaPlayerreset()released()并设置为null只是为了确保垃圾收集器尽快处理。

释放并取消媒体播放器onCompletionListener中的所有发生者,并且当我在作为onCompletion()方法的参数传入的MediaPlayer上执行reset(),release()和null时,reset()和release()操作正常,但不能设置为null。但是,如果我使用MediaPlayer的父类实例,那么reset(),release()和null化就可以了。现在我的问题是,有什么区别?它是同一个对象。

澄清问题的一个例子。

public class SoundHandler {
    private MediaPlayer mediaPlayer;

    playSignal(Context context) {
        mediaPlayer = new MediaPlayer();

        // ...Further preparation of mediaPlayer omitted

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.reset(); // Works
                mp.release(); // Works
                mp = null; // Fails, contains the same memory reference as before...
            }
        });
    }
}

public class SoundHandler {
    private MediaPlayer mediaPlayer;

    playSignal(Context context) {
        mediaPlayer = new MediaPlayer();

        // ...Further preparation of mediaPlayer omitted

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mediaPlayer.reset(); // Works
                mediaPlayer.release(); // Works
                mediaPlayer= null; // Works, object is null after this assignment
            }
        });
    }
}

我不知道区别是什么,我真的想解释一下。

谢谢!

1 个答案:

答案 0 :(得分:1)

在第一种情况下,MediaPlayer设置为null是方法的参数。 Java使用'按引用传递'语义,因此您的方法的参数只是SoundHandler对该对象的引用的副本,而不是SoundHandler自己对它的引用。

因此,您可以将方法的参数视为局部变量。将其设置为null时,效果仅为本地(在您的方法中)。 SoundHandler仍有它自己的参考。

然而,在第二种情况下,onCompletionListener直接将SoundHandler对MediaPlayer的引用设置为null。它可以这样做,因为onCompletionListener是SoundHandler的匿名内部类。