Android SeekBar setProgress导致我的MediaPlayer跳过

时间:2011-01-09 19:05:35

标签: android multithreading audio-player android-music-player

我正在尝试使用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状态以响应UI事件。但是,我真正的问题是音乐正在跳过。

有没有人可以建议另一种方法来更新进度并解释为什么即使使用单独的线程调用setProgress导致音轨跳过?

提前致谢。

1 个答案:

答案 0 :(得分:26)

我认为问题是当你调用setProgress()时,会触发onProgressChanged事件。

监听器(OnSeekBarChangeListener)有一个方法 public void onProgressChanged(SeekBar seekBar,int progress,boolean fromUser)。在这里,您应该测试监听器是由用户操作还是从代码触发的。 在您的情况下,fromUser变量应为false。

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