Android SeekBar setProgress заставляет мой MediaPlayer пропускать
Я пытаюсь использовать SeekBar, чтобы отображать как длину трека, воспроизводимого классом MediaPlayer, так и возможность поиска в треке.
Поиск в пределах трека хорошо работает. Однако обновление значения прогресса с помощью setProgress во время воспроизведения дорожки приводит к небольшому пропуску.
В методе onCreate я создаю Thread с циклом, который обновляет значение прогресса SeekBar для текущего трека. Этот цикл сбрасывается при изменении дорожки.
private void createProgressThread() {
_progressUpdater = new Runnable() {
@Override
public void run() {
//Exitting is set on destroy
while(!_exitting) {
_resetProgress = false;
if(_player.isPlaying()) {
try
{
int current = 0;
int total = _player.getDuration();
progressBar.setMax(total);
progressBar.setIndeterminate(false);
while(_player!=null && current<total && !_resetProgress){
try {
Thread.sleep(1000); //Update once per second
current = _player.getCurrentPosition();
//Removing this line, the track plays normally.
progressBar.setProgress(current);
} catch (InterruptedException e) {
} catch (Exception e){
}
}
}
catch(Exception e)
{
//Don't want this thread to intefere with the rest of the app.
}
}
}
}
};
Thread thread = new Thread(_progressUpdater);
thread.start();
}
В идеале я бы предпочел не использовать нить, поскольку я понимаю, что это имеет недостатки. Также, пожалуйста, извините за исключением глотания - трудно проверить все состояния MediaPlayer в ответ на события пользовательского интерфейса. Однако моя реальная проблема заключается в том, что музыка пропускается.
Может ли кто-нибудь предложить альтернативный способ обновления прогресса и объяснить, почему вызов setProgress вызывает прохождение дорожки даже с использованием отдельного потока?
Спасибо заранее.
Ответы
Ответ 1
Я думаю, проблема заключается в том, что при вызове setProgress() запускается событие onProgressChanged.
У слушателя (OnSeekBarChangeListener) есть метод
public void onProgressChanged (SeekBar seekBar, int progress, boolean fromUser). Здесь вы должны проверить, был ли слушатель запущен действием пользователя или из кода.
В вашем случае переменная fromUser должна быть ложной.
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){
player.seekTo(x);
}
else{
// the event was fired from code and you shouldn't call player.seekTo()
}
}