2012-06-21 4 views
2

Предположим два потока: мой поток и поток MediaPlayer (который отправляет мне через петлеровщик). Моя игровая нить реагирует на ввод пользователя: , если пользователь приостанавливает геймплей, я вызываю MediaPlayer.pause().Поведение Android MediaPlayer (гарантии порядка событий)

Рассмотрит следующий порядок событий:

  1. медиаплеер аудио поток достигает свою цель, так что ставит в очереди OnCompletion сообщения мне
  2. Моей нити: MediaPlayer.pause() Вызывается из-за действия пользователя
  3. Я получаю OnCompletion вызов (слишком поздно, пауза() уже под названием выше)

Проблема с этим я что MediaPlayer.pause() разрешен только в состоянии PAUSED и STARTED, но из-за шага 1 MediaPlayer будет уже находиться в PlaybackCompleted состоянии, когда вызывается pause(). Я вижу два решения:

  1. Ловля исключения
  2. просит MediaPlayer.isPlaying() перед вызовом паузы()

Но второе решение имеет проблемы в следующем сценарии:

  1. Игра начата, MediaPlayer.start() называется, но состояние медиапланера еще нет НАЧАЛО
  2. Пользователь оставляет игровой процесс, вызывая код: if (isPlaying()) pause();
  3. MediaPlayer входит НАЧАТЬ состояние (теперь isPlaying вернется правда, но слишком поздно)

Проблема здесь состоит в том, что isPlaying() будет возвращать ложь (как документы говорят, тоже), так что MediaPlayer будет все еще запускаются из-за шага 3.

Есть ли решение, которое является правильным и позволяет избежать исключений в обоих случаях? (Или есть какая-либо ошибка в моем выше ходе мыслей?)


Update

В ответ на ответ Geobits' (я делаю это здесь, потому что я цитирую Android документа):

Да, я также занимаюсь локальным воспроизведением, проверял его так же, как и вы, и все выглядело отлично. Но документация немного противоречива. Первая часть (это нормально):

Вызов старт(), чтобы возобновить воспроизведение для приостановленного объекта MediaPlayer, и возобновил воспроизведение положение такое же, как, где она была приостановлена. Когда вызов функции start() возвращает приостановленный объект MediaPlayer, возвращается обратно в начальное состояние.

И еще одна цитата из той же странице:

Воспроизведение может быть приостановлена ​​и остановилась, и текущее положение воспроизведения можно регулировать. Воспроизведение можно приостановить с помощью паузы(). Когда вызов pause() возвращается, объект MediaPlayer переходит в состояние Paused. Примечание о том, что переход от состояния Started к приостановленному состоянию и наоборот происходит асинхронно в игровом движке. Это может занять некоторое время до того, как состояние будет обновлено при звонках на isPlaying(), а это может быть несколько секунд в случае потокового содержимого.

Этот последний один говорит, что и при начиная приостановленной игрок, изменение состояния может занять некоторое время («наоборот»). Пока все хорошо, потому что оно применимо только к внутреннему игровому движку, но затем приходит сумасшедшая часть: «Может потребоваться некоторое время, прежде чем состояние будет обновлено при вызовах isPlaying()». Это означает, что isPlaying() не возвращает состояние НАБЛЮДАЕМОГО, а зависит от внутреннего состояния. Это смущает.

ответ

2

Я сделал несколько приложений с MediaPlayer и каждый раз использовал if(isPlaying()) pause(); без каких-либо плохих эффектов. Это с местными СМИ. Если вы выполняете потоковую передачу, это может вызвать проблемы второго типа.

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

Но попробуйте сначала. Это хорошо для меня, и я сыграл дерьмо из моего.

+0

Спасибо за подтверждение. Несколько дней назад, чтобы быть уверенным, я применил обходное решение (фактически безупречное) решение, да. Тем не менее, мои результаты такие же, как у вас, но документация действительно сбивает с толку в определенной части: см. Мой исходный вопрос для цитат (я обновил его в конце). –

+1

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

+0

Еще одно противоречивое: можно ли вызывать pause() в состоянии PlaybackCompleted или нет. Согласно документации, вы не можете (она переходит в состояние ошибки), но на практике вы можете. И учитывая, что вы не можете проверить синхронно, будет ли воспроизведение завершено (у вас есть только обратный вызов onCompletion), вы не можете знать (без трюков), если ваш вызов pause() безопасен или нет. Я отправил им вопрос, но ответа пока нет: http://groups.google.com/group/android-platform/browse_thread/thread/5ed3ed460880c0fc# –

Смежные вопросы