Android L SoundPool.load()回归

时间:2014-10-26 19:42:53

标签: android android-5.0-lollipop soundpool

在Android L上 - 最新的开发者预览版(Nexus 5),SoundPool.load()方法似乎存在回归,加载样本(<100kb)需要大约5秒钟,其中加载了样本使用完全相同的代码立即在pre-L系统上。

我尝试了OGG或MP3,两者都有相同的结果。尝试了不同的尺寸但都低于100kb。似乎40kb或80kb没有任何区别,OGG或MP3也是如此。加载总是大约5s延迟。

这似乎是在4.3中打破循环后SoundPool中的另一个回归。

该问题很容易重现:

    pool = new SoundPool(6, AudioManager.STREAM_MUSIC, 0);
    // use a listener to start playback after load
    pool.setOnLoadCompleteListener(listener);

    // R.raw.sound1 is either an OGG or MP3 sample under 100kb od size
    int id = pool.load(context, R.raw.sound1, 1);

    // onLoadComplete() method of the listener is called several seconds after the call to laod()

使用Builders引入的API 21构建SoundPool也是如此:

    AudioAttributes attr = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();

    pool = new SoundPool.Builder().setAudioAttributes(attr).setMaxStreams(6).build();

还有其他人遇到这种情况吗?有人找到了解决方法吗?

非常感谢!

1 个答案:

答案 0 :(得分:2)

大家都知道,这是一个众所周知的错误:

我尝试过多线程......从某种意义上说它没有阻止应用程序正常工作!但是你需要知道在加载所有声音之前你不能调用Soundpool.load方法。即使您对已加载的声音调用加载,也会导致应用冻结。我猜SoundPool类有某种类型的内部同步。无论如何,您可以使用此方法使您的应用程序工作。这是一个可以提供帮助的片段:

 private class loadSFXasync extends AsyncTask<String, Integer, Long> {
     protected Long doInBackground(String... str) {
         int count = str.length();
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             mSoundPool.load(str,1);
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         mAllSoundsAreLoaded=true;
     }
 }

并在您的代码中:

playSound(String str){
    if (!mAllSoundsAreLoaded)
    return;
    // otherwise: do mSoundPool.load(....)
}