我遇到了 Android 的 MediaPlayer.OnCompletionListener()
行为,我无法解释,我希望有人可以向我解释。
我已经实现了一个实用程序类,它负责在我的应用程序中使用 MediaManager
进行所有处理。用例是我创建并准备一个 MediaPlayer
对象,一旦完成播放,MediaPlayer
就会 reset()
,released ()
并设置为 null
只是为了确保垃圾收集器尽快处理它。
这会释放并取消媒体播放器 onCompletionListener 中的所有事件,当我在 MediaPlayer 上执行 Reset()、release() 和 null 作为参数传递给 onCompletion()
方法时,reset( ) 和release() 操作正常,但不能设置为null。但是,如果我使用 MediaPlayer 的父类实例,则重置(),释放()和无效化就可以了。现在我的问题是,有什么区别?这是同一个对象。
一个澄清问题的例子。
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
}
});
}
}
我不明白有什么区别,我真的很想对此进行解释。
谢谢!
最佳答案
在第一种情况下,设置为 null 的 MediaPlayer 是该方法的一个参数。 Java 使用“按引用传递”语义,因此方法的参数只是 SoundHandler 对该对象的引用的副本,而不是 SoundHandler 自己对该对象的引用。
因此,您可以将方法的参数视为局部变量。当您将其设置为 null 时,效果仅是局部的(在您的方法内)。 SoundHandler 仍然有它自己的引用。
然而,在第二种情况下,onCompletionListener 直接将 SoundHandler 对 MediaPlayer 的引用设置为 null。它可以做到这一点,因为 onCompletionListener 是 SoundHandler 的匿名内部类。
关于java - Android MediaPlayer.OnCompletionListener() 的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28178429/