我有一个游戏,当一个关卡完成时会播放声音。一切正常,但在重复10或20次后,logcat突然报告: “MediaPlayer错误(-19,0)”和/或“MediaPlayer在状态0中调用”并且不再发出声音。
我最初的所有声音都是mp3格式,但是在阅读ogg可能更可靠之后,我将它们全部转换为ogg,但错误看起来是一样的。
知道如何解决这个问题吗?
答案 0 :(得分:68)
我遇到了同样的问题,我通过添加以下代码来解决它,以释放播放器:
mp1 = MediaPlayer.create(sound.this, R.raw.pan1);
mp1.start();
mp1.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.release();
};
});
答案 1 :(得分:61)
我认为你没有发布用于播放声音的媒体播放器 .. 您需要释放()媒体播放器,否则资源不会被释放,您很快就会内存不足(因为下次再分配它们)。所以,我认为你可以玩两次甚至三次......但没有多次没有释放资源
答案 2 :(得分:15)
当您播放小型音效时,MediaPlayer 不是一个好的选择,因为用户可以很快点击多个按钮,您将不得不为所有这些按钮创建一个MP对象,它不是同步发生的。这就是为什么你没有听到每次点击的声音。转到SoundPool类,它允许您将较小的声音保存在内存中,您可以随时播放它们而不会出现媒体播放器中的任何延迟。 http://developer.android.com/reference/android/media/SoundPool.html这是一个很好的教程:http://www.anddev.org/using_soundpool_instead_of_mediaplayer-t3115.html
答案 3 :(得分:2)
我解决了两个错误(-19,0)和(-38,0),每次在播放之前创建一个MediaPlayer的新对象,之后再发布它。
之前:
void play(int resourceID) {
if (getActivity() != null) {
//Using the same object - Problem persists
player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
之后:
void play(int resourceID) {
if (getActivity() != null) {
//Problem Solved
//Creating new MediaPlayer object every time and releasing it after completion
final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
答案 4 :(得分:1)
我尝试删除模拟器和新的创建模拟器以删除(-19,0)媒体播放器的错误。
答案 5 :(得分:1)
这是一个非常古老的问题,但这在我的搜索结果中首先出现,所以其他有相同问题的人最终可能会出现在这个页面上。
与其他人所说的不同,事实上你可以在不使用大量内存的情况下将MediaPlayer用于小声音。我会从我的音板应用程序中添加一些修改过的snippit来向你展示我的目标。
private MediaPlayer mp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
mp = new MediaPlayer();
}
private void playSound(int soundID){
mp.reset();
AssetFileDescriptor sound = getResources().openRawResourceFd(soundID);
try {
mp.setDataSource(sound.getFileDescriptor(),sound.getStartOffset(),sound.getLength());
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mp.start();
}
按照我设置的方式,您在MediaPlayer对象上创建,每次播放声音时都可以重复使用,这样就不会占用太多空间。
您调用.reset()而不是.release(),因为.release()仅在您处置对象时使用,但是您要保留MediaPlayer对象。
您使用assetfiledescriptor为您的媒体播放器设置新的声音文件,而不是将新对象设置为您的媒体播放器地址,因为您正在方法中创建未正确处理的新对象,您最终将运行与您描述的错误相同。
这只是使用MediaPlayer的众多方法之一,但我个人认为如果您只将它用于小型声音应用程序,它是最有效的。唯一的问题是它在你可以完成的事情上是相对限制性的,但如果你确实将它用于小型声音应用程序,这不应该是一个很大的问题。