本文总结SoundPool的使用方法及注意事项,同时结合MediaPlayer分析两者的差异。
在Android应用开发中我们经常需要播放多媒体声音文件,一般会使用MediaPlayer类,但该类占用资源较多,对于游戏等应用可能不是很适合。SoundPool(声音池)类主要用来播放一些较短的声音片段,可以从程序的资源或文件系统加载,相对于MediaPlayer类占用较少的CPU资源并具备较短的反应延迟。
SoundPool和其他声音播放类相比,其特点是可行设置声音的以自品质、音量、播放比率等参等。它可以同时管理多个音频流,每个流都有独自的ID,通过ID对音频流进行管理。
SoundPool基本使用方法如下:
1.new一个实例
new SoundPool(int maxStreams, int streamType, int srcQuality);
/*
maxStream —— 同时播放的流的最大数量
streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值
比如说: new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
创建了一个最多支持4个流同时播放的,类型标记为音乐的SoundPool。
*/
2.加载资源
一般把多个声音放到HashMap中去,比如:
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(1, soundPool.load(this, R.raw.ring, 1));
当然,我们也可以加载单个的Music,那我们怎么实现播放指定的Music呢?
有关载入音效的方法,有以下几种方法:
// 从apk资源载入
Int load(Context context, int resId, int priority)
// 从FileDescriptor对象载入
Int load(FileDescriptor fd, long offset, long length, int priority)
// 从Assert对象载入
Int load(AssertFileDescriptor afd, int priority)
// 从完整路径名载入
Int load(String path, int priority)
在这里,最后一个参数priority是处理优先级,播放多个文件时,系统优先处理优先级高的文件
3.播放
play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate);
//其中soundID,就是load方法得到的那个int型参数,leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率,速率最低0.5最高为2,1代表正常速度
4.停止
pause(int streamID) ; //这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始
5.没有声音
没有就对了。因为在play(..)之前Soundpool没有初始化(load)完毕。那我们如何知道load已经完毕了呢?
Android提供了检测是否初始化完毕的方法,SoundPool.OnLoadCompleteListener(sdk 2.2)
-----------------------------------------------------------Hello World !---------------------------------------------------
下面分析下MediaPlayer与SoundPool的利弊:
@使用MediaPlayer来播放音频文件存在的一些不足:
例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。
这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想。游戏里面经常要同时播放几个音乐文件,用过MediaPlayer的朋友都该知道,它是不支持实时播放多个声音的,而且还会出现或多或少的延迟,尤其是在快速连续播放声音(比如连续猛点按钮)时,会非常明显,长的时候会出现3~5秒的延迟,因此一般游戏开发使用的都是Soundpool。
@使用SoundPool存在的一些问题:
<!--[if !supportLists]-->1. <!--[endif]-->SoundPool是为播放小文件而存在的。一般限定Soundpool播放文件的大小为1M。
2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3. 音频格式建议使用OGG格式。使用WAV格式的音频文件存放游戏音效,经过反复测试,在音效播放间隔较短的情况下会出现异常关闭的情况(有说法是SoundPool目前只对16bit的WAV文件有较好的支持)。
4.在使用SoundPool播放音频的时候,如果在初始化中就调用播放函数进行播放音乐那么根本没有声音,不是因为没有执行,而是SoundPool需要——准备时间!这就是刚刚我们说的用OnLoadCompleteListener来解决的问题。
5. 在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool:
1.应用程序中的声效(按键提示音,消息等)
2.游戏中密集而短暂的声音(如多个飞船同时爆炸)
3. …