Android媒体播放器崩溃的应用程序



我有一个安卓应用程序,它有一个播放声音的按钮。播放声音的代码:

if (mp != null)
{
    mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.start();

mp是活动中的一个字段:

public class Game extends Activity implements OnClickListener {
/** Called when the activity is first created. */
//variables:
MediaPlayer mp;
//...

该应用程序运行正常,但在模拟器上点击按钮约200次后,应用程序崩溃,并给了我这个错误https://dl.dropbox.com/u/5488790/error.txt(不知道如何将其张贴在这里,这样它会显得很得体)
我假设这是因为MediaPlayer对象消耗了太多内存,但mp.release()不应该处理这个问题吗?我在这里做错了什么?

如果将音效附加到按钮,MediaPlayer通常对该操作来说太重了。你每次都会得到不必要的延迟,只是为了把声音数据加载到内存中。您应该考虑使用SoundPool

在任何一种情况下,都没有正当理由每次发布和重新创建MediaPlayer。如果您决定使用MediaPlayer,请通过单击按钮控制您拥有的单个实例。

MediaPlayer mp;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Other init code
    //Create the player this way so it doesn't auto-prepare
    mp = new MediaPlayer();
    AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.match);
    mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
    afd.close();
}
public void onDestroy() {
    super.onDestroy();
    //Release it only when no longer needed
    mp.release();
    mp = null;
}
public void onButtonClick(View v) {
    if (mp.isPlaying()) {
        mp.stop();
    }
    //Play the sound
    mp.prepare();
    mp.start();
}

希望这有帮助,但再次强调,如果这个声音只是一个短暂的效果,我强烈建议使用SoundPool

看起来您的代码应该可以工作,但显然release()并没有真正发布所有内容。

也许是因为每次你想播放声音时都必须重新加载R.raw.match。如果R.raw.match只是一个简短的音效,那么您可能需要考虑使用SoundPool

如果使用SoundPool,则只需加载R.raw.match一次,这可能会防止内存问题。

本教程有一个关于如何使用它的好例子:http://www.vogella.com/articles/AndroidMedia/article.html#tutorial_soundpool

你几乎只需要制作一个SoundPool实例,然后加载一次声音,并在需要时播放。

希望这能有所帮助!

编辑

如果您想使用MediaPlayer。。。

public class Blah extends Activity implements OnClickListener {
   MediaPlayer mp;
   @Override 
   public void onCreate(Bundle b)
   {
      // blah blah
      mp = MediaPlayer.create(R.raw.match);
      // blah blah
   }
   @Override
   public void onClick(View v)
   {
      if (v.getId() == yourButtonID)
      {
         // play sound from beginning
         mp.seekTo(0);
         mp.start();
      }
   }
}

这样,你只创建一个实例,每当你想播放它时,你只需将它倒带到开头,然后播放。

尝试

if (mp != null)
        {
            mp.release();
        }
        mp = MediaPlayer.create(this, R.raw.match);
        mp.prepare(); // not needed 
        mp.start();

祝你好运!!

如果您持有MediaPlayer,请在活动结束时释放它

@Override
void onDestroy() {
    if (mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
    super.onDestroy();
}

最新更新