我对Android MediaPlayer有一个有趣的情况。我在活动中需要播放大约30种声音。我得到了一些奇怪的结果,我不确定是否会出现内存问题...
我需要使用媒体播放器的原因是我有一个定时流向声音,其中一个声音需要以一定顺序播放另一个声音。我还使用回调来查看下一个播放的声音。因此,soundpool出局......
我尝试使用MediaPlayer.create()将每个声音加载到自己的媒体播放器中。现在,这在我的设备上工作正常,三星Galaxy S Vibrant。然而,当我尝试设置onCompletionListener时,我的带有Samsung Ace的客户端会出现空指针异常,这意味着.create()在他的设备上返回null但不是我的。
所以,我从一次加载它们切换到在前一个声音using this method的onCompletionListener中即时加载它们
这种作品,第3-4个声音播放然后它挂在我客户端的设备上(在我的设备上仍能正常工作)。我假设它挂在.prepare()
上这很难理清,因为我的客户端并不真正了解logcat,也没有SDK可以调试,而且它在我的设备上运行正常。它甚至挂在他的第二台设备上,该设备与我的型号相同。
任何人都知道可能导致此问题或如何调试它?
我认为我的下一步就是只使用一个MediaPlayer并使用OnCompletionListener的mp参数在同一个媒体播放器上加载下一个声音。我会发表我的发现。
答案 0 :(得分:1)
如果您正在正确发布媒体播放器,则不应该是内存问题。您可以通过执行以下操作来正确地确保这一点:
if(mediaplayer!=null){
if(mediaplayer.isPlaying()){
mediaplayer.stop();
}
mediaplayer.release();
mediaplayer = null;
}
我认为对于apk内存分配有10MB的限制(最低,有些手机更高),所以你应该能够在你的限制范围内检查这种情况。然而,市场将允许高达50MB。
对于调试,我建议你确保所有的声明都在那里(听起来很傻,但它会把它排除在外),因为如果你错过了声音文件,它当然无法创建。如果抛出异常,则创建Toast
通知,例如IllegalStateException
将确保您管理媒体播放器状态不是问题。
值得一提的是,您不应该混用prepare
和create
。如果您使用create
,则会调用prepare
,之后对prepare
的调用可能会导致奇怪的行为;不确定它是否会使玩家无效!
一般情况下,您不希望按照提议的方式(创建新的媒体播放器并更改onComplete
中的声音)。原因很简单,当你拨打create
或prepare
时,它会将声音加载到内存中 - 这将花费不同的时间取决于手机(这可能是一个非常长的时间一些手机!)。最好一次加载它们。
答案 1 :(得分:1)
所以,它一定是某种内存问题。我最初加载了20多个媒体播放器。
现在我将它们全部合并到一个媒体播放器中并动态加载声音。声音很小,所以我不担心加载时间。
以下是一些帮助代码,以防万一有人想要它。
private MediaPlayer getMediaPlayer(MediaPlayer mp, int resID, OnCompletionListener listener){
mp.release();
mp = null;
mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(resID);
try {
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
mp.prepare();
mp.setOnCompletionListener(listener);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return mp;
}
我用它来加载一个新的声音。它有一点开销,但它有效,这才是最重要的。
以下是我如何使用它。
mSoundPlayer = getMediaPlayer(mSoundPlayer, R.raw.a123switch, endSwitch123Listener);
mSoundPlayer.start();