SoundPool(android.media.SoundPool),顾名思义是声音池的意思,主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载。与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。
SoundPool存在的缺陷
1.SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
2.SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。建议使用这两个方法的时候尽可能多做测试工作,还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3.SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,但是有的朋友在G1中测试它还是有100ms左右的延迟,这可能会影响用户体验。也许这不能管SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。
在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool:1.应用程序中的声效(按键提示音,消息等)2.游戏中密集而短暂的声音(如多个飞船同时爆炸)
import android.media.AudioManager;
import android.media.SoundPool;
SoundPool soundPool;//声明SoundPool对象
//soundPool实例化,第一个参数为soundPool可以支持的声音数量,这决定了Android为其开设多大的缓冲区,第二个参数为声音类型,在这里标识为系统声音,除此之外还有AudioManager.STREAM_RING以及AudioManager.STREAM_MUSIC等,系统会根据不同的声音为其标志不同的优先级和缓冲区,最后参数为声音品质,品质越高,声音效果越好,但耗费更多的系统资源。
soundPool= new SoundPool(10,AudioManager.STREAM_SYSTEM,5);
//系统为soundPool加载声音 第一个参数为上下文参数,第二个参数为声音的id,第三个参数为声音的优先级,当多个声音冲突而无法同时播放时,系统会优先播放优先级高的。一般我们将声音信息保存在res的raw文件夹下
//载入音频流,返回在池中的id
int sourceid = soundPool.load(this,R.raw.collide,1);
//播放,第一个参数为id,id即为放入到soundPool中的顺序,比如现在collide.wav是第一个,因此它的id就是1。第二个和第三个参数为左右声道的音量控制。第四个参数为优先级,由于只有这一个声音,因此优先级在这里并不重要。第五个参数为是否循环播放,0为不循环,-1为循环。最后一个参数为播放比率,从0.5到2,一般为1,表示正常播放。
soundPool.play(1,1, 1, 0, 0, 1);
注意:
如果SoundPool刚调完加载load函数之后,直接调用SoundPool的play函数可能出现
error "sample 1 not READY"
所以建议,调用加载资源函数load之后,实现资源加载结束的监听函数,在这个监听到资源加载结束之后,播放音频文件。
如:
SoundPool soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 5);
//载入音频流,返回在池中的id
final int sourceid = soundPool.load(mContext, R.raw.move_sound, 0);
//播放音频,第二个参数为左声道音量;第三个参数为右声道音量;第四个参数为优先级;第五个参数为循环次数,0不循环,-1循环;第六个参数为速率,速率最低0.5最高为2,1代表正常速度
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// TODO Auto-generated method stub
soundPool.play(sourceid, 2, 2, 0, 0, 1);
}
});