2011-11-26 35 views
1

我有一个有趣的情况与Android MediaPlayer。我有大约30种声音需要在活动中播放。我得到奇怪的结果,我不知道是否来自内存问题或不...Android媒体播放器悬挂或返回null

我需要使用媒体播放器的原因是,我有一个定时流动的声音,其中一个声音需要按照一定的顺序依次玩。我也使用回调来查看下一个播放的声音。因此,soundpool是出...

我试过将每个声音加载到它自己的媒体播放器使用MediaPlayer.create()。现在,这款Samsung Galaxy S Vibrant设备可以正常工作。然而,当我尝试设置onCompletionListener时,我的三星Ace的客户端正在获取空指针异常,这意味着.create()在他的设备上返回null,但不是我的。

所以,我从加载它们一次全部切换到以前的声音using this method

这类工程的onCompletionListener,加载它们在飞行拳头3-4声音播放,然后将其挂在我客户端设备(在我的设备上仍能正常工作)。我假设它挂在.prepare()

这非常难以理清,因为我的客户端没有真正的logcat知识,也没有SDK来调试,并且它在我的设备上工作正常。它甚至挂在他的第二个与我的模型相同的设备上。

任何人都知道什么可能会导致这个或如何调试它?

我在想我的下一步将只是使用一个MediaPlayer并使用OnCompletionListener的mp参数在同一个媒体播放器上加载下一个声音。我会发布我的发现。

回答

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(); 
1

如果您正确释放媒体播放器,它不应该是内存问题。你可以适当地确保这一点做:

if(mediaplayer!=null){ 
     if(mediaplayer.isPlaying()){ 
      mediaplayer.stop(); 
     } 
     mediaplayer.release(); 
     mediaplayer = null; 
} 

我相信这是一个10MB的限制(最小,有的手机是更高版本)APK内存分配,所以你应该能够检查这个适合你的范围之内。不过,市场将允许高达50MB。

对于调试,我建议你确保所有的声明都在那里(听起来很愚蠢,但它排除了),因为如果你错过了声音文件,它当然无法创建。如果抛出异常,则创建Toast通知IllegalStateException将确保您管理媒体播放器状态不成问题。

还值得一提的是,你不应该混合preparecreate。如果您使用的是create,则它将会呼叫prepare,随后对prepare的呼叫可能会导致奇怪的行为;不知道它是否会使玩家无效!

一般而言,您不想按照您的建议(创建新媒体播放器并更改onComplete中的声音)进行。原因很简单,当你拨打createprepare时,它会将声音加载到内存中 - 这需要花费不同的时间,这取决于手机(对于某些手机来说这可能是一段非常长的时间!)。一次加载它们会更好。

+0

感谢您的基本检查。我知道有时候最简单的解决方案可能是对的。但不是在这种情况下:) 我不混合创建和准备。我试图创建它们,最终在某个时候给了我一个从.create()返回的空值。 –

+0

感谢您的帮助,我的方法结束了工作,并发布它作为答案,我虽然你有+1。 –