Android Media Player зависает или возвращает ноль - PullRequest
1 голос
/ 27 ноября 2011

У меня интересная ситуация с Android MediaPlayer. У меня около 30 звуков, которые мне нужно сыграть в упражнении. Я получаю странные результаты, которые я не уверен, из-за проблем с памятью или нет ...

Причина, по которой мне нужно использовать медиаплеер, заключается в том, что у меня есть синхронизированный поток звуков, где один звук должен воспроизводиться за другим в определенном порядке. Я также использую обратные вызовы, чтобы увидеть, какой звук воспроизводится следующим. Таким образом, саундпул вышел ...

Я попытался загрузить каждый звук в свой собственный медиаплеер, используя MediaPlayer.create (). Теперь, это работает отлично на моем устройстве, Samsung Galaxy S Vibrant. Мой клиент с Samsung Ace, однако, получает исключения нулевого указателя, когда я пытаюсь установить onCompletionListener, то есть .create () возвратил null на его устройстве, но не на моем.

Итак, я переключился с загрузки их всех сразу на загрузку их на лету в onCompletionListener предыдущего звука , используя этот метод

Этот тип работает, звучит первый 3-4 звук, а затем он зависает на устройстве моего клиента (все еще работает нормально на моем устройстве). Который я предполагаю, что он висит на .prepare ()

Это невероятно сложно разобраться, так как мой клиент не имеет реального знания logcat и SDK для отладки, и он отлично работает на моем устройстве. Он даже висит на его втором устройстве, которое является той же моделью, что и мое.

Кто-нибудь знает, что может быть причиной этого или как его отладить?

Я думаю, что моим следующим шагом будет просто использовать один MediaPlayer и использовать параметр mp OnCompletionListener для загрузки следующего звука на том же медиаплеере. Я опубликую свои выводы.

Ответы [ 2 ]

1 голос
/ 28 ноября 2011

Итак, это должно быть какая-то проблема с памятью. У меня было загружено более 20 медиаплееров.

Теперь я объединил их все в один медиаплеер и загружаю звуки динамически. Звуки небольшие, поэтому меня не беспокоит время загрузки.

Вот некоторый вспомогательный код на случай, если кто-то захочет.

private MediaPlayer getMediaPlayer(MediaPlayer mp, int resID, OnCompletionListener listener){
mp.release();
mp = null;
mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(resID);
try {
    mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
    mp.prepare();
    mp.setOnCompletionListener(listener);
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IllegalStateException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
return mp;
}

Я использую это для загрузки нового звука. У него немало накладных расходов, но это работает, и вот что важно.

Вот как я это использую.

mSoundPlayer = getMediaPlayer(mSoundPlayer, R.raw.a123switch, endSwitch123Listener);
mSoundPlayer.start();
1 голос
/ 27 ноября 2011

Если вы правильно выпускаете медиаплеер, это не должно быть проблемой памяти.Вы можете должным образом убедиться в этом, выполнив:

if(mediaplayer!=null){
        if(mediaplayer.isPlaying()){
            mediaplayer.stop();
        }
        mediaplayer.release();
        mediaplayer = null;
}

Я считаю, что существует ограничение в 10 МБ (минимум, некоторые телефоны выше) для распределения памяти apk, поэтому вы должны быть в состоянии проверить это в своих пределах.Однако на рынке будет доступно до 50 МБ.

Для отладки я предлагаю вам убедиться, что все оценки есть (звучит глупо, но это исключает), поскольку, если вы пропустите звуковые файлы, это, конечно, будетне в состоянии создать.Создание Toast уведомлений, если генерируется исключение, например, IllegalStateException гарантирует, что управление состояниями медиаплеера не является проблемой.

Стоит также отметить, что вам никогда не следует смешивать prepare и create.Если вы используете create, он уже будет вызывать prepare, и последующие вызовы prepare могут вызвать странное поведение;хотя я не уверен, что это приведет к аннулированию плеера!

В общем, вы не хотите делать это так, как вы предлагаете (создание нового медиаплеера и изменение звука в onComplete).Причина этого проста, когда вы звоните create или prepare, он загружает звук в память - это займет переменное количество времени в зависимости от телефона (это может быть очень долго для некоторых телефонов!),Гораздо лучше загрузить их все сразу.

...