强调!!!以下只是我个人看法,如有错误的地方请文明指出,如有其他看法请耐心讨论
,如有看不懂可以参考其他有关博客
,最后如有想喷的出门左转不谢。
上次有提到用MediaPlayer来播放音频,但是要播放密集的,短促的音效还是用SoundPool好。主要是MediaPlayer资源占用率较高,延时时间较长,不支持多个音频同时出现。
SoundPool使用了音效池的概念管理多个音效,它可以同时加载很多音效,然后根据音效的ID值进行播放。SoundPool的优势在于CPU资源占用量低,反应延迟小,另外SoundPool还支持自行设置声音的品质、音量、播放频率等参数。
注:从Android5.0开始SoundPool的构造器被设置为过时,因此推荐使用SoundPool.Builder来创建SoundPool对象。
获得了SoundPool对象后,接下来就可以调用SoundPool的多个重载的load()方法来加载声音了,返回值是int类型的id值。
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对应的文件加载声音。
注;上面四个方法中都有int priority的参数,该参数目前还没有任何作用,Android建议将该参数设置为1,保持和未来的兼容性。
加载声音之后,要根据返回的id值来播放声音了,用到了SoundPool提供的Play()方法来播放指定的声音。
int play(int soundID,float leftVoiume,float rightVolume,int priority,int loop,float rate):该方法的第一个参数指定播放哪个声音,第二、三各参数指定播放的音量,priority指定播放声音的优先级,数值越大,优先级别越高;loop指定是否循环,0为不循环,-1为循环;rate指定播放的比率,数值可以从0.5到2,1为正常比率。
注:为了更好地管理SoundPool所加载的每个声音的ID,程序一般会使用HashMap<Integer,Integer>对象来管理声音。
总之,使用SoundPool播放声音的步骤如下:
1、调用SoundPool.Builder的构造器创建SoundPool.Builder对象,并通过该Builder对象为SoundPool设置属性。
2、调用SoundPool的构造器创建SoundPool对象。
3、调用SoundPool对象的load()方法从指定资源、文件中加载声音。最好使用HasMap<Integer,Integer>来管理所加载的声音。
4、调用SoundPool的play()方法播放声音。
小例子(有三个按钮来播放声音):
import java.util.HashMap;import android.app.Activity;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;public class OtherActivity extends Activity {Button bomb,shot,arrow;//定义一个SoundPoolSoundPool soundPool;HashMap<Integer,Integer> soundMap = new HashMap<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_other);bomb = (Button) findViewById(R.id.bomb);shot = (Button) findViewById(R.id.shot);arrow = (Button) findViewById(R.id.arrow);AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME)//设置音效使用场景//设置音效的类型.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();soundPool = new SoundPool.Builder().setAudioAttributes(attr)//设置音效池的属性.setMaxStreams(10)//设置最多可容纳10个音频流.build();//load方法加载指定音频文件,并返回所加载的音频ID//此处使用HashMap来管理这些音频流soundMap.put(1,sounPool.load(this,R.raw.bomb,1));soundMap.put(2,sounPool.load(this,R.raw.shot,1));soundMap.put(3,sounPool.load(this,R.raw.arrow,1));bomb.setOnClickListener(this);shot.setOnClickListener(this);arrow.setOnClickListener(this);}//重写OnClickListener监听接口private void onClick(View source) {//判断哪个按钮被单击switch(source.getId()){case R.id.bomb:soundPool.play(soundMap.get(1), 1, 1, 0, 0, 1);break;case R.id.shot:soundPool.play(soundMap.get(2), 1, 1, 0, 0, 1);break;case R.id.arrow:soundPool.play(soundMap.get(3), 1, 1, 0, 0, 1);break;}}
}
实际上使用SoundPool播放声音是要注意以下几点:
SoundPool虽然可以一次加载多个声音,但由于内存限制,因此应该避免用SoundPool播放比较大的音频比如歌曲和游戏的背景音乐。
虽然SoundPool的效率比MediaPlayer好,但也不是绝对不存在延时问题,尤其是在那些性能不大好的手机上,SoundPool的延时会非常严重。