了解在 Android 1.6/2.0/2.1 上使用 SoundPool 加载声音是不是成功
Posted
技术标签:
【中文标题】了解在 Android 1.6/2.0/2.1 上使用 SoundPool 加载声音是不是成功【英文标题】:Knowing if the loading of a sound with SoundPool has been successful on Android 1.6/2.0/2.1了解在 Android 1.6/2.0/2.1 上使用 SoundPool 加载声音是否成功 【发布时间】:2011-01-14 15:19:31 【问题描述】:在 android 2.2+ 上,有一个名为 SoundPool.OnLoadCompleteListener 的东西可以知道声音是否已成功加载。
我的目标是较低的 API 版本(最好是 1.6,但可以使用 2.1),我需要知道声音是否已正确加载(因为它是由用户选择的)。正确的方法是什么?
我希望不要使用 MediaPlayer 加载一次声音,如果使用 SoundPool 正确?!
【问题讨论】:
好问题,我也遇到了同样的问题 (***.com/questions/3253108/…),但并没有真正找到解决方案。 【参考方案1】:我实现了一种兼容的 OnLoadCompleteListener
类,它至少适用于 Android 2.1。
构造函数采用SoundPool
对象,并且已调用SoundPool.load(..)
的声音必须向OnLoadCompleteListener.addSound(soundId)
注册。在此之后,听众会定期尝试播放请求的声音(以零音量)。如果成功,它会调用您的 onLoadComplete
实现,就像在 Android 2.2+ 版本中一样。
这是一个用法示例:
SoundPool mySoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
OnLoadCompleteListener completionListener = new OnLoadCompleteListener(mySoundPool)
@Override
public void onLoadComplete(SoundPool soundPool, int soundId, int status)
Log.i("OnLoadCompleteListener","Sound "+soundId+" loaded.");
int soundId=mySoundPool.load(this, R.raw.funnyvoice,1);
completionListener.addSound(soundId); // tell the listener to test for this sound.
这是来源:
abstract class OnLoadCompleteListener
final int testPeriodMs = 100; // period between tests in ms
/**
* OnLoadCompleteListener fallback implementation for Android versions before 2.2.
* After using: int soundId=SoundPool.load(..), call OnLoadCompleteListener.listenFor(soundId)
* to periodically test sound load completion. If a sound is playable, onLoadComplete is called.
*
* @param soundPool The SoundPool in which you loaded the sounds.
*/
public OnLoadCompleteListener(SoundPool soundPool)
testSoundPool = soundPool;
/**
* Method called when determined that a soundpool sound has been loaded.
*
* @param soundPool The soundpool that was given to the constructor of this OnLoadCompleteListener
* @param soundId The soundId of the sound that loaded
* @param status Status value for forward compatibility. Always 0.
*/
public abstract void onLoadComplete(SoundPool soundPool, int soundId, int status); // implement yourself
/**
* Method to add sounds for which a test is required. Assumes that SoundPool.load(soundId,...) has been called.
*
* @param soundPool The SoundPool in which you loaded the sounds.
*/
public void addSound(int soundId)
boolean isFirstOne;
synchronized (this)
mySoundIds.add(soundId);
isFirstOne = (mySoundIds.size()==1);
if (isFirstOne)
// first sound, start timer
testTimer = new Timer();
TimerTask task = new TimerTask() // import java.util.TimerTask for this
@Override
public void run()
testCompletions();
;
testTimer.scheduleAtFixedRate(task , 0, testPeriodMs);
private ArrayList<Integer> mySoundIds = new ArrayList<Integer>();
private Timer testTimer; // import java.util.Timer for this
private SoundPool testSoundPool;
private synchronized void testCompletions()
ArrayList<Integer> completedOnes = new ArrayList<Integer>();
for (Integer soundId: mySoundIds)
int streamId = testSoundPool.play(soundId, 0, 0, 0, 0, 1.0f);
if (streamId>0) // successful
testSoundPool.stop(streamId);
onLoadComplete(testSoundPool, soundId, 0);
completedOnes.add(soundId);
mySoundIds.removeAll(completedOnes);
if (mySoundIds.size()==0)
testTimer.cancel();
testTimer.purge();
【讨论】:
【参考方案2】:SoundPool 会异步加载文件。在 API8 级别之前,遗憾的是没有 API 可以检查加载是否已完成。
正如您所说,从 Android API8 开始,可以通过 OnLoadCompleteListener 检查加载是否完成。这是一个小例子:Android sounds tutorial。
【讨论】:
以上是关于了解在 Android 1.6/2.0/2.1 上使用 SoundPool 加载声音是不是成功的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何在 Android 地址上了解一个国家是不是有州?
Android内存优化1 了解Android是如何管理App内存