Android L SoundPool.load() регрессия

В Android L - последний предварительный просмотр разработчика (Nexus 5), похоже, существует регресс в методе SoundPool.load(), который занимает > 5 секунд, чтобы загрузить образец (< 100kb), где были загружены образцы pre-L мгновенно с тем же кодом.

Я попробовал OGG или MP3, оба с одинаковыми результатами. Пробовали разные размеры, но все под 100kb. Кажется, что 40kb или 80kb не имеет никакого значения, так же как OGG или MP3. Загрузка всегда составляет 5 с.

Кажется, что еще одна регрессия в SoundPool после того, как в 4.3 была разбита петля.

Проблема легко воспроизводится с помощью:

    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()

То же самое происходит для построения SoundPool с использованием API-интерфейсов Builders, представленных следующим образом:

    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

Только так вы, ребята, знаете, это известная ошибка:

Я пробовал многопоточность... Он работает нормально в некотором смысле, что он не блокирует приложение! Но вам нужно знать, что вы не можете вызвать метод 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(....)
}