重复播放后Mediaplayer错误(-19,0)

时间:2012-03-27 11:14:27

标签: android android-mediaplayer

我有一个游戏,当一个关卡完成时会播放声音。一切正常,但在重复10或20次后,logcat突然报告: “MediaPlayer错误(-19,0)”和/或“MediaPlayer在状态0中调用”并且不再发出声音。

我最初的所有声音都是mp3格式,但是在阅读ogg可能更可靠之后,我将它们全部转换为ogg,但错误看起来是一样的。

知道如何解决这个问题吗?

6 个答案:

答案 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的众多方法之一,但我个人认为如果您只将它用于小型声音应用程序,它是最有效的。唯一的问题是它在你可以完成的事情上是相对限制性的,但如果你确实将它用于小型声音应用程序,这不应该是一个很大的问题。