Android SoundPool load优化

来源:互联网 发布:淘宝代理怎么做 编辑:程序博客网 时间:2024/06/09 13:38

最近在测试程序的时候发现,SoundPool的load()方法在主线程里创建多了就会很卡顿。

我在Frament里的onCreateView()方法里面加载了14个声音明显的感觉到了卡顿。

所以我这里做的优化就是点击按钮之后才再去加载和播放声音,这样可以避免主线程性能的消耗



思路已经知道了,立马我就想到这样去写:

soundPool.play(soundPool.load(context, R.raw.num0, 1), 1, 1, 1, 0, 1);

写了之后测试时立马就出现问题了,什么情况~没有声音了!
原来load()方法是异步的。也就是说我在play播放的时候load方法还没有加载完成呢。


所以OnLoadCompleteListener这个接口就派上用场了。以下是我写一个数字键盘简单计算器小程序可以播放声音(实现点击按钮之后再去加载和播放声音的效果)。别的不多说了直接贴上源码了:


public class MySoundPool {/** * 创建一个声音池 * @param MaxStreams 最大流数量 * @return */@SuppressWarnings("deprecation")public static SoundPool Create(int MaxStreams) {SoundPool soundPool;if (Build.VERSION.SDK_INT >= 21) {AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);Builder SoundPoolbuild = new SoundPool.Builder();SoundPoolbuild.setMaxStreams(MaxStreams);SoundPoolbuild.setAudioAttributes(attrBuilder.build());soundPool = SoundPoolbuild.build();} else {soundPool = new SoundPool(MaxStreams, AudioManager.STREAM_MUSIC, 5);}return soundPool;}}

主要实现类:

private int nowSoundNum;private SoundPool soundPool;private OnLoadCompleteListener SoundLoadListener;private HashMap<Integer, Integer> soundID = new HashMap<Integer, Integer>();private static final int mNum0 = 0;private static final int mNum1 = 1;private static final int mNum2 = 2;private static final int mNum3 = 3;private static final int mNum4 = 4;private static final int mNum5 = 5;private static final int mNum6 = 6;private static final int mNum7 = 7;private static final int mNum8 = 8;private static final int mNum9 = 9;private static final int mNum10dian = 10;private static final int mNum11jia = 11;private static final int mNum12clear = 12;private static final int mNum13bk = 13;public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);soundPool = MySoundPool.Create(14);// 创建声音池...}public void onClick(View v) {switch (v.getId()) {case R.id.btn_0:PlaykeyboardSound(mNum0);break;case R.id.btn_1:PlaykeyboardSound(mNum1);break;case R.id.btn_2:PlaykeyboardSound(mNum2);break;...}}private void PlaykeyboardSound(int key) {nowSoundNum = key;if (soundID.get(key) == null) {if (SoundLoadListener == null) {SoundLoadListener = new OnLoadCompleteListener() {@Overridepublic void onLoadComplete(SoundPool soundPool,int sampleId, int status) {SaveSoundIDandPlay(sampleId);}};soundPool.setOnLoadCompleteListener(SoundLoadListener);}switch (key) {case mNum0:soundPool.load(activity, R.raw.num0, 1);break;case mNum1:soundPool.load(activity, R.raw.num1, 1);break;case mNum2:soundPool.load(activity, R.raw.num2, 1);break;case mNum3:soundPool.load(activity, R.raw.num3, 1);break;case mNum4:soundPool.load(activity, R.raw.num4, 1);break;case mNum5:soundPool.load(activity, R.raw.num5, 1);break;case mNum6:soundPool.load(activity, R.raw.num6, 1);break;case mNum7:soundPool.load(activity, R.raw.num7, 1);break;case mNum8:soundPool.load(activity, R.raw.num8, 1);break;case mNum9:soundPool.load(activity, R.raw.num9, 1);break;case mNum10dian:soundPool.load(activity, R.raw.num10point, 1);break;case mNum11jia:soundPool.load(activity, R.raw.num11jia, 1);break;case mNum12clear:soundPool.load(activity, R.raw.num12clear, 1);break;case mNum13bk:soundPool.load(activity, R.raw.num13delete, 1);break;}} else {soundPool.play(soundID.get(key), 1, 1, 0, 0, 1);}}private synchronized void SaveSoundIDandPlay(int sampleId) {soundPool.play(sampleId, 1, 1, 1, 0, 1);soundID.put(nowSoundNum, sampleId);}

saveSoundIDAndPlay方法为什么要加同步锁。其实还是因为load的原因,因为load是异步的。当saveSoundIDAndPlay方法不加同步锁的时候,你快速点击多个按钮后这几个按钮的声音同时开始加载了,就有可能同时播放了,所以还是要让它按顺序播放。

 



0 0