Предположим два потока: мой поток и поток MediaPlayer (который отправляет мне через петлеровщик). Моя игровая нить реагирует на ввод пользователя: , если пользователь приостанавливает геймплей, я вызываю MediaPlayer.pause().Поведение Android MediaPlayer (гарантии порядка событий)
Рассмотрит следующий порядок событий:
- медиаплеер аудио поток достигает свою цель, так что ставит в очереди OnCompletion сообщения мне
- Моей нити: MediaPlayer.pause() Вызывается из-за действия пользователя
- Я получаю OnCompletion вызов (слишком поздно, пауза() уже под названием выше)
Проблема с этим я что MediaPlayer.pause() разрешен только в состоянии PAUSED и STARTED, но из-за шага 1 MediaPlayer будет уже находиться в PlaybackCompleted состоянии, когда вызывается pause(). Я вижу два решения:
- Ловля исключения
- просит MediaPlayer.isPlaying() перед вызовом паузы()
Но второе решение имеет проблемы в следующем сценарии:
- Игра начата, MediaPlayer.start() называется, но состояние медиапланера еще нет НАЧАЛО
- Пользователь оставляет игровой процесс, вызывая код: if (isPlaying()) pause();
- MediaPlayer входит НАЧАТЬ состояние (теперь isPlaying вернется правда, но слишком поздно)
Проблема здесь состоит в том, что isPlaying() будет возвращать ложь (как документы говорят, тоже), так что MediaPlayer будет все еще запускаются из-за шага 3.
Есть ли решение, которое является правильным и позволяет избежать исключений в обоих случаях? (Или есть какая-либо ошибка в моем выше ходе мыслей?)
Update
В ответ на ответ Geobits' (я делаю это здесь, потому что я цитирую Android документа):
Да, я также занимаюсь локальным воспроизведением, проверял его так же, как и вы, и все выглядело отлично. Но документация немного противоречива. Первая часть (это нормально):
Вызов старт(), чтобы возобновить воспроизведение для приостановленного объекта MediaPlayer, и возобновил воспроизведение положение такое же, как, где она была приостановлена. Когда вызов функции start() возвращает приостановленный объект MediaPlayer, возвращается обратно в начальное состояние.
И еще одна цитата из той же странице:
Воспроизведение может быть приостановлена и остановилась, и текущее положение воспроизведения можно регулировать. Воспроизведение можно приостановить с помощью паузы(). Когда вызов pause() возвращается, объект MediaPlayer переходит в состояние Paused. Примечание о том, что переход от состояния Started к приостановленному состоянию и наоборот происходит асинхронно в игровом движке. Это может занять некоторое время до того, как состояние будет обновлено при звонках на isPlaying(), а это может быть несколько секунд в случае потокового содержимого.
Этот последний один говорит, что и при начиная приостановленной игрок, изменение состояния может занять некоторое время («наоборот»). Пока все хорошо, потому что оно применимо только к внутреннему игровому движку, но затем приходит сумасшедшая часть: «Может потребоваться некоторое время, прежде чем состояние будет обновлено при вызовах isPlaying()». Это означает, что isPlaying() не возвращает состояние НАБЛЮДАЕМОГО, а зависит от внутреннего состояния. Это смущает.
Спасибо за подтверждение. Несколько дней назад, чтобы быть уверенным, я применил обходное решение (фактически безупречное) решение, да. Тем не менее, мои результаты такие же, как у вас, но документация действительно сбивает с толку в определенной части: см. Мой исходный вопрос для цитат (я обновил его в конце). –
Да, документация для этого класса ужасно запутанна, независимо от того, сколько хороших диаграмм и диаграмм они добавляют. Я почти разорвал свои проклятые волосы, пытаясь заставить вакелока работать правильно во всех ситуациях. – Geobits
Еще одно противоречивое: можно ли вызывать pause() в состоянии PlaybackCompleted или нет. Согласно документации, вы не можете (она переходит в состояние ошибки), но на практике вы можете. И учитывая, что вы не можете проверить синхронно, будет ли воспроизведение завершено (у вас есть только обратный вызов onCompletion), вы не можете знать (без трюков), если ваш вызов pause() безопасен или нет. Я отправил им вопрос, но ответа пока нет: http://groups.google.com/group/android-platform/browse_thread/thread/5ed3ed460880c0fc# –