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就三个按钮,在此省略了。