我正在尝试编写一个函数来在我的程序中播放一个简短的声音(在/ res / raw中),在整个程序中有效地随机调用。到目前为止,我有这个功能:
public void playSound() {
MediaPlayer mp = new MediaPlayer();
mp = MediaPlayer.create(this, R.raw.ShortBeep);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(false);
mp.start();
}
它可以正常工作一段时间,但经过30次播放声音后,它就会停止发声。
答案 0 :(得分:7)
...无法调用release()可能导致MediaPlayer对象的后续实例回退到软件实现或完全失败。
完成后,请致电mp.release()
,以便释放资源。我不知道限制是什么,我相信它取决于很多因素。无论哪种方式,您都应该在MediaPlayer
对象上调用此函数,尤其是如果它将被多次使用。
答案 1 :(得分:0)
我刚解决了完全相同的问题,但我正在使用Xamarin。我最终在活动的生命周期中从保持更改为MediaPlayer实例,每次我想播放声音时都创建实例。我还实现了IOnPreparedListener和IOnCompletionListener。
希望你能得到这个想法,尽管它是C#代码
public class ScanBarcodeView :
MvxActivity,
MediaPlayer.IOnPreparedListener,
MediaPlayer.IOnCompletionListener
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.ScanBarcodeView);
((ScanBarcodeViewModel) ViewModel).BarcodeScanFailed += (sender, args) => PlaySound(Resource.Raw.fail);
((ScanBarcodeViewModel) ViewModel).DuplicateScan += (sender, args) => PlaySound(Resource.Raw.tryagain);
}
private void PlaySound(int resource)
{
var mp = new MediaPlayer();
mp.SetDataSource(ApplicationContext, Android.Net.Uri.Parse($"android.resource://com.company.appname/{resource}"));
mp.SetOnPreparedListener(this);
mp.SetOnCompletionListener(this);
mp.PrepareAsync();
}
public void OnPrepared(MediaPlayer mp)
{
mp.Start();
}
public void OnCompletion(MediaPlayer mp)
{
mp.Release();
}
}
因此,每次我想要播放声音时,我都会创建一个MediaPlayer实例,所以数据源告诉它我的Activity是Prepared和Completion事件的监听器并准备它。由于我正在使用PrepareAsync,因此我不会阻止UI线程。准备媒体播放器时,将调用MediaPlayer上的Start方法,并在声音播放完毕后释放MediaPlayer对象。
在我做出这些更改之前,我会播放30个声音并且它将全部停止工作。现在我已经过了30岁,也可以同时播放多个声音。
希望有所帮助。