SoundPool一般用来播放的文件特点有:声音短,文件小,延时慢(不像使用MediaPlayer类播放音乐时,需要等待一段时间),因此常用来播放游戏时的音效,解锁时的铃声等。注意:该类不适合播放太大的文件资源,我测试了个900K左右的文件,播放不了
使用SoundPool一般需要下面几个步骤:
1、将音乐文件拷贝到工程下;
2、新建一个SoundPool实例;
3、使用load()方法,让SoundPool实例加载音效资源,该方法会返回一个整型的soundID,在第四步需要用到;
4、使用play()方法播放音效,该方法会返回一个整型的streamID,这个返回值可以保存起来,在需要暂停 / 恢复播放时需要用到。
具体实现以及参数如下:
1、新建一个工程,我取名SoundPoolDemo,在res文件夹下新建一个raw文件夹,将.mp3文件拷贝到其中
2、新建一个SoundPool实例。SoundPool只有一个构造方法,
SoundPool(int maxStreams, int streamType, int srcQuality)
参数如下:
int maxStreams:在声音池中允许同时存在的声音数量。当池子中的声音超过这个数量时,优先级(后面会提到)最低、或者最早(Oldest,原谅我可怜的翻译水平)放进池中的,将被移除。这个数值不是越大越好,因为越大也就意味着,Android会给你预分配一个更大的空间,如果不需要使用会造成浪费。
int streamType:声音流的类型,有STREAM_RING、STREAM_MUSIC等等,一般都是使用后者,即AudioManager.STREAM_MUSIC。
int srcQuality:官网解释为“采样速率转化器的质量”(再次原谅我的翻译),这个参数目前没有什么实际意义(可能还没实现这个功能),所以设置什么数值都无所谓,官方建议用0;
3、加载资源方法:
public int load(Context context, int resId, int priority)
参数如下:
Context context:这个不必多解释,一般都是设置为getApplicationContext()获取
int resId:想要加载的音效资源ID,我用的是R.raw.XXX
int priority:音效播放时的优先级,官方解释这个参数在这个方法中不起作用,建议用1暂时代替(Currently has no effect. Use a value of 1 for future compatibility.)
注:该方法会返回一个soundID,在以后使用中需要使用
4、播放
07-08注:在load声音资源后,并不能立即调用play,否则无法播放声音,因为声音资源还没加载完成,应该给足够时间让它加载完成,比如在onCreate中load,在onclick中play
public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
参数如下:
int soundID:在第3步中提到了。
float leftVolume:左声道音量大小,这是一个相对值,大小在0.0f - 1.0f之间,具体计算方法为:你想要的声音大小 / 最大音量,比如取值0.8f表示最大音量的80%
float rightVolume:右声道音量大小,具体如上
int priority:优先级,值越大优先级越高,0的优先级最低。之前在第3步中也有一个优先级参数,但是那里无效,而现在这里的这个参数是正儿八经有效果的。
int loop:是否需要循环播放,取值不限。其中负数表示无穷循环(官方建议,如果无穷循环,用-1,当然-2、-3等也行),非负数表示循环次数,比如0表示循环0次,也就是播放一次就不再循环了,总共就只播放一次;1则表示循环1次(总共播放2次)。
float rate:这个参数有点意思,可以理解为播放速率(就是快进、快退啥的),取值0.5f - 2.0f,其中0.5表示播放速度为正常的0.5倍。1表示正常速率播放。
下面开始正式编码:
1、资源文件如下图:
2、布局文件不解释了,只有一个简单的Button。下面是MainActivity.java的代码(总共就一个类)
package com.exam.soundpooldemo;
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 MainActivity extends Activity {
Button playButton;
SoundPool sp;
int soundID_1,soundID_2;
int streamID_1,streamID_2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sp=new SoundPool(10, AudioManager.STREAM_MUSIC,0);
soundID_1=sp.load(getApplicationContext(), R.raw.lingsheng, 1);
soundID_2=sp.load(getApplicationContext(), R.raw.moon, 1);
playButton=(Button)findViewById(R.id.play);
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
streamID_1=sp.play(soundID_1, 0.8f, 0.8f,1, -1, 1.0f);
streamID_2=sp.play(soundID_2, 0.8f, 0.8f,1, -1, 1.0f);
}
});
}
}
发现按下按钮,可以听到两种音效同时播放(因为我的代码中是播放2种)。
尾声:
前面提到播放音效的方法play()会返回一个streamID,这个返回值在暂停 / 恢复时需要用到,比如恢复:
public final void resume (int streamID)
看到了吧,所以最好用一些变量将他们保存起来。
如果还有不懂的,可以直接参考API:
http://www.android-doc.com/reference/android/media/SoundPool.html