我有一个安卓应用程序,它有一个播放声音的按钮。播放声音的代码:
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();
}