SoundPool —— 适合短促且对反应速度比较高的情况(游戏音效或按键声等)
1.SoundPool的创建
根据API可知:
1.当SDK版本高于或等于21时,用SoundPool.Builder创建
SoundPool.Builder builder=new SoundPool.Builder();
2.当SDK版本低于21时,用SoundPool创建。
SoundPool pool=new SoundPool(2, AudioManager.STREAM_MUSIC,0);
2.加载音频资源
先在res下新建一个名raw的resource directory文件,将ogg格式的音频放在这个文件下
可以通过四种途径来记载一个音频资源:
int load(AssetFileDescriptor afd, int priority)
通过一个AssetFileDescriptor对象
int load(Context context, int resId, int priority)
通过一个资源ID
int load(String path, int priority)
通过指定的路径加载
int load(FileDescriptor fd, long offset, long length, int priority)
通过FileDescriptor加载
*API中指出,其中的priority参数目前没有效果,建议设置为1。
一个SoundPool能同时管理多个音频,所以可以通过多次调用load函数来记载,如果记载成功将返回一个非0的soundID ,用于播放时指定特定的音频。
需要注意的是,
流的加载过程是一个将音频解压为原始16位PCM数据的过程,由一个后台线程来进行处理异步,所以初始化后不能立即播放,需要等待一点时间。
3.播放控制
1.play()函数传递的是一个load()返回的soundID——指向一个被记载的音频资源 ,如果播放成功则返回一个非0的streamID——指向一个成功播放的流 ;同一个soundID 可以通过多次调用play()而获得多个不同的streamID (只要不超出同时播放的最大数量);
2.pause()、resume()和stop()是针对播放流操作的,传递的是play()返回的streamID ;
3.play()中的priority参数,只在同时播放的流的数量超过了预先设定的最大数量是起作用,管理器将自动终止优先级低的播放流。如果存在多个同样优先级的流,再进一步根据其创建事件来处理,新创建的流的年龄是最小的,将被终止;
4.无论如何,程序退出时,手动终止播放并释放资源是必要的。
5.释放资源
可操作的函数有:
final boolean unload(int soundID)
卸载一个指定的音频资源.
final void release()
释放SoundPool中的所有音频资源.
下面对以上进行总结:
一个SoundPool可以:
1.管理多个音频资源,通过load()函数,成功则返回非0的soundID;
2.同时播放多个音频,通过play()函数,成功则返回非0的streamID;
3.pause()、resume()和stop()等操作是针对streamID(播放流)的;
4.当设置为无限循环时,需要手动调用stop()来终止播放;
5.播放流的优先级(play()中的priority参数),只在同时播放数超过设定的最大数时起作用;
6.程序中不用考虑(play触发的)播放流的生命周期,无效的soundID/streamID不会导致程序错误。
实例
package com.example.administrator.mysoundpool;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private Button mBtnSoundPool;
private SoundPool pool=null;
private int voiceID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnSoundPool= (Button) findViewById(R.id.btn_soundpool);
mBtnSoundPool.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playSound();
}
});
voiceID= initSoundPool();
}
public void playSound(){
pool.play(voiceID,1,1,0,-1,1);
}
private int initSoundPool(){
if(Build.VERSION.SDK_INT>=21){ //判断SDK的版本
SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder attrbuilder=new AudioAttributes.Builder();
builder.setAudioAttributes(attrbuilder.build());
pool=builder.build();
}else {
pool=new SoundPool(2, AudioManager.STREAM_MUSIC,0);
}
return pool.load(getApplicationContext(),R.raw.outgoing,0);
}
}