Android SoundPool load优化

最近在测试程序的时候发现,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 soundID = new HashMap();
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() {
				@Override
				public 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方法不加同步锁的时候,你快速点击多个按钮后这几个按钮的声音同时开始加载了,就有可能同时播放了,所以还是要让它按顺序播放。

 




你可能感兴趣的:(Android,SoundPool,load优化)