SoundPool 加载缓慢,MotionEvent 很奇怪
Posted
技术标签:
【中文标题】SoundPool 加载缓慢,MotionEvent 很奇怪【英文标题】:SoundPool loads slowly and is weird with MotionEvent 【发布时间】:2020-09-13 18:39:30 【问题描述】:嗨! 我对编程很陌生,我遇到了一些关于 SoundPool 的问题。 我正在尝试构建一个简单的钢琴应用程序,但尚未找到解决方案。我使用的音频文件是 midi (.mid)
我的代码当前存在的问题:
音频文件加载速度很慢,我必须等待几秒钟才能让 SOUND_12 准备好。 如果我只用一根手指,它可以正常工作,但是当我添加另一根手指时,第一根手指/声音会卡住。我当前的代码:
public class MainActivityPiano extends AppCompatActivity
//all soundIDs
public static final int SOUND_1 = 1;
public static final int SOUND_2 = 2;
SoundPool mSoundPool;
HashMap<Integer, Integer> mSoundMap;
static int streamID;
@Override
protected void onStart()
super.onStart();
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
mSoundMap = new HashMap<Integer, Integer>();
if(mSoundPool != null)
mSoundMap.put(SOUND_1, mSoundPool.load(this, R.raw.piano_tone1, 1));
mSoundMap.put(SOUND_2, mSoundPool.load(this, R.raw.piano_tone2, 1));
//at least twelve different sound files have to be loaded...
//play buttons and/or piano keys
Button pianoKey1 = this.findViewById(R.id.piano_key1);
Button pianoKey2 = this.findViewById(R.id.piano_key2);
//...
//play buttons and/or pianokeys
pianoKey1.setOnTouchListener(new View.OnTouchListener()
public boolean onTouch(View view, MotionEvent motionEvent)
return playSound(SOUND_1, motionEvent, view);
);
pianoKey2.setOnTouchListener(new View.OnTouchListener()
public boolean onTouch(View view, MotionEvent motionEvent)
return playSound(SOUND_2, motionEvent, view);
);
//...
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_piano);
public boolean playSound(int sound, MotionEvent m, View v)
switch (m.getAction())
case MotionEvent.ACTION_DOWN:
streamID = mSoundPool.play(sound, 1, 1, 1, 0, 1.0f);
break;
case MotionEvent.ACTION_CANCEL:;
mSoundPool.stop(streamID);
break;
case MotionEvent.ACTION_UP:
mSoundPool.stop(streamID);
break;
case MotionEvent.ACTION_MOVE:
return true;
@Override
protected void onPause()
mSoundPool.autoPause();
super.onPause();
【问题讨论】:
【参考方案1】:您可能希望预加载声音,然后通过引用它们的 id 来播放它们。
short[]
数组将包含您传递给 getSound()
的 fileNames
中相应文件的 ID
创建一个单独的类Sound.java
:
在您的 Main Activity 中,您可以创建一个 Sound
对象并在 onCreate()
中加载一次声音并使用它们的 id 播放它们。
public class Sound
private static SoundPool soundPool;
public short[] getSound(Activity activity, String...fileNames)
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
short[] ids = new short[fileNames.length];
activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
try
AssetManager assetManager = activity.getAssets();
for(int i = 0; i < fileNames.length; i++)
AssetFileDescriptor descriptor = assetManager.openFd(fileNames[i]);
ids[i] = (short) soundPool.load(descriptor, 1);
catch(IOException e)
//
return ids;
public void playSound(short id, float rV, float lV)
if(id != -1)
soundPool.play(id, rV, lV, 0, 0, 1);
public void pauseSound()
soundPool.autoPause();
public void releaseSound()
soundPool.release();
【讨论】:
太棒了!谢谢,但我如何处理多点触控而不让声音卡住?以上是关于SoundPool 加载缓慢,MotionEvent 很奇怪的主要内容,如果未能解决你的问题,请参考以下文章