随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)
MediaPlayer有两个缺陷:资源占用量较高、延迟时间较长。不支持多个音频同时播放。
所以如果程序需要播放密集、短促的音效,这时还用MediaPlayer就不合适了。应该使用SoundPool来播放,SoundPool使用音效池的概念来管理多个短促的音效,可以一开始就加载很多个音效,以后就按音效的ID进行播放。SoundPool的优势在于CPU资源占用量低和反应延迟小。还支持自行设置声音的品质、音量、播放比率等参数。
通过构造方法可以得到SoundPool对象,然后就可以调用load() 方法加载声音了。
int load(Context context ,int resId,int priority):从resId所对应的资源加载声音。
int load(FileDescriptor fd,long offset,long length,int priority):加载fd所对应的文件的offset开始、长度为length的声音。
int load(AssetFileDescriptor afd,int priority):从afd所对应的文件中加载声音。
int load(String path,int priority):从path对应的文件去加载声音。
上面方法中priority参数,目前还没有任何作用,Android建议设为1,保持和未来的兼容性。上面四个方法都会返回声音的ID,以后程序就可以根据ID来播放指定声音,方法如下:
int play(int soundID,float leftVolume,float rightVolume,int priority,int loop,float rate):第一个参数是声音的ID,leftVolume,rightVolume指定左、右的音量;priority指定声音的优先级,数值越大,优先级越高;loop指定是否循环,0为不循环,-1为循环;rate指定播放的比率,数值可从0.5到2,1为正常比率。
下面用一个简单示例来演示SoundPool的使用:
Activity:
package com.home.activity;
import java.util.Collection;
import java.util.HashMap;
import com.home.testsoundpool.R;
import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class TestSoundPoolActivity extends Activity implements OnClickListener {
private Button soundBtn1;
private Button soundBtn2;
private Button soundBtn3;
// 声明SoundPool对象
private SoundPool soundPool;
// 使用HashMap集合管理所加载的声音
private HashMap<Integer, Integer> soundMap = new HashMap<Integer, Integer>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
soundBtn1 = (Button) findViewById(R.id.test_sound_main_btn_sound1);
soundBtn2 = (Button) findViewById(R.id.test_sound_main_btn_sound2);
soundBtn3 = (Button) findViewById(R.id.test_sound_main_btn_sound3);
soundBtn1.setOnClickListener(this);
soundBtn2.setOnClickListener(this);
soundBtn3.setOnClickListener(this);
// 创建对象,第一个参数为最多可容纳的音频流,第二参数为声音类型,第三个参数为声音的品质
soundPool = new SoundPool(3, AudioManager.STREAM_SYSTEM, 5);
// load方法加载指定音频文件,并返回所加载的音频的ID
soundMap.put(1, soundPool.load(this, R.raw.s1, 1));
soundMap.put(2, soundPool.load(this, R.raw.s2, 1));
soundMap.put(3, soundPool.load(this, R.raw.s3, 1));
}
@Override
public void onClick(View v) {
if (v == soundBtn1) {
// 播放声音
soundPool.play(soundMap.get(1), 1, 1, 1, -1, 1);
}
if (v == soundBtn2) {
soundPool.play(soundMap.get(2), 1, 1, 1, -1, 1);
}
if (v == soundBtn3) {
soundPool.play(soundMap.get(3), 1, 1, 1, -1, 1);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 得到集合中所有音频流的id
Collection<Integer> col = soundMap.values();
for (Integer id : col) {
soundPool.stop(id);
}
}
}
布局XML就三个按钮,在此省略了。