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