使用SoundPool的基本流程是:创建一个SoundPool对象、载入要播放的音频、播放某个音频、停止播放某个音频。
一个SoundPool对象可以载入多个音频,每个音频载入后对应一个SoundID。播放某个音频时用SoundID指定要播放的音频,并返回播放该音频的ChannelID。要停止播放某个音频,需要通过其ChannelID,注意不是SoundID!使用SoundPool播放音频的示意图如下:
下面用SoundPool编写一个播放音效的应用,可以单次、循环播放音效,界面如下:
有的设备上循环播放参数无效,可以采用Thread来实现。应用主要代码如下:
SoundPool类的主要方法包括:
1)构造函数:SoundPool(int maxStreams, int streamType, int srcQuality)。第一个参数maxStreams指定同时支持多少个声音,即Channel数量;第二个参数streamType指定声音类型,一般游戏中用AudioManager.STREAM_MUSIC;第三个参数srcQuality指定声音品质,目前没用,给0即可。
2)载入音频的load方法一共有4个,这里只列出最常用的两个:
int load(Context context, int resld, int priority):从 resld 所对应的资源加载音频
int load(String path, int priority):从path对应的文件去加载音频
priority参数,目前没用,Android建议设为1,保持和未来的兼容性;加载音频之后都会返回该声音的ID,以后可以通过ID来播放指定音频。
3)播放音频:int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)。第一个参数soundID指定播放哪个声音;第二三个参数leftVolume、rightVolume指定左、右的音量;第四个参数priority指定播放声音的优先级,数值越大,优先级越高;第五个参数loop指定是否循环,0为不循环,-1为循环;经测试目前无效;第六个参数rate指定播放的比率,数值可从0.5到2, 1为正常比率;返回播放该音频的ChannelID,也叫StreamID,用此ID来对播放进行控制,如停止、暂停等。
4)卸载音频:boolean unload(int soundID)。卸载soundID指定的音频,成功返回true。
5)释放所有资源:void release()。
例子的完整代码如下:
public class MainActivity extends AppCompatActivity {int[] soundResId = {R.raw.fly, R.raw.fire, R.raw.explode}; // 音频资源SoundPool soundPool;int[] soundId; // soundPool为每个装入的音频资源生成的SoundIDint flyStreamId; // soundPool播放fly音频时使用的Channel,通过Channel控制音效播放PlayThread playThread; // 因为SoundPool的循环播放功能无效,所以用Thread来实现循环播放@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);LinearLayout ll = new LinearLayout(this);ll.setOrientation(LinearLayout.VERTICAL);setContentView(ll);soundId = new int[soundResId.length];soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 100); // 创建SoundPool对象for(int i=0; i<soundResId.length; i++)soundId[i] = soundPool.load(this, soundResId[i], 1); // 依次载入音频资源,生成的SoundID存入soundId数组,播放时使用Button btnFire = new Button(this);btnFire.setText("Fire");ll.addView(btnFire);btnFire.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View arg0) {soundPool.play(soundId[1], 1, 1, 1, 0, 1); // 播放fire音频,其SoundID存放在soundId[1]}});Button btnExplode = new Button(this);btnExplode.setText("Explode");ll.addView(btnExplode);btnExplode.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View arg0) {soundPool.play(soundId[2], 1, 1, 1, 0, 1); // 播放explode音频,其SoundID存放在soundId[2]}});Button btnStartFly = new Button(this);btnStartFly.setText("Start Fly");ll.addView(btnStartFly);btnStartFly.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View arg0) {flyStreamId = soundPool.play(soundId[0], 1, 1, 1, -1, 1f); // 控制循环播放的参数无效//playThread = new PlayThread(soundId[0], 3000); // 启用一个线程,每隔3000毫秒播放一次fly音频,其长度大约为3000毫秒//playThread.start();}});Button btnStopFly = new Button(this);btnStopFly.setText("Stop Fly");ll.addView(btnStopFly);btnStopFly.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View arg0) {soundPool.stop(flyStreamId);//playThread.stopPlay();}});}@Overrideprotected void onDestroy(){super.onDestroy();soundPool.release();}class PlayThread extends Thread {boolean flag;int soundId;int streamId;int duration;public PlayThread(int sId, int d){soundId = sId;duration = d;}public void run(){flag = true;while(flag){streamId = soundPool.play(soundId, 1, 1, 1, 0, 1f); // 播放音频soundIdtry {sleep(duration); // 等待该音频的播放时间} catch (InterruptedException e) {e.printStackTrace();}}}public void stopPlay(){soundPool.stop(streamId); // 立即停止SoundPool的streamId频道的播放flag = false; // 停止播放循环}}
}