mediaplayer.getCurrentPosition обновляется рывками

196
19 апреля 2018, 12:54

Я запускаю поток, который создаю этим методом:

         void UIInitialize(){
                UIUpdater = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (!UIUpdater.isInterrupted()) {
        //блок паузы потока для того, что-бы включать его только на время работы
                            synchronized (UIMonitor) {
                                while (!isUpdUI) {
                                    try {
                                        UIMonitor.wait();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace(); return;
                                    }
                                }
                            }
                            if (mediaPlayer != null) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                    int CurrentProgress = mediaPlayer.getCurrentPosition();
                                    Log.e("Thread", "SendUiUpd: "+CurrentProgress);
                                    tvProgress.setText(String.valueOf(CurrentProgress));
                                    }
                                });
                            } else {
                                isUpdUI=false;}
                            try {
                                Thread.sleep(15);
                            } catch (InterruptedException e) {
                               return;
                            }
                        }
                    }
                });
                UIUpdater.start();
            }

В лог

04-17 18:27:09.907 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2873
04-17 18:27:09.924 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2890
04-17 18:27:09.940 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2906
04-17 18:27:09.957 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926
04-17 18:27:09.959 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926
04-17 18:27:09.973 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926
04-17 18:27:09.988 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926
04-17 18:27:10.003 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926
04-17 18:27:10.022 27365-27365/etere.wingscontrol E/Thread: SendUiUpd:2926

Сделав задержку равной 1 удалось заметить закономерность, оно проскакивает промежуток в 0.5-0.7 секунды корректно с быстрой сменой цифр, а потом на 0.3-0.7 секунд подвисает, а потом опять быстро корректно работает (похоже проблема в буферизации?)

В результате изучения логов было замечено, что к моменту паузы getCurrentTime превышает реально прошедшее время, а по выходу становится равным... а то и вовсе вот такой прикол...(04-17 20:26:37.559 E/Thread: SendUiUpd: 0 - первый апдейт)

04-17 20:26:39.212 E/Thread: SendUiUpd: 1658
04-17 20:26:39.218 E/Thread: SendUiUpd: 1664 - рельное время - 1.659
04-17 20:26:39.220 E/Thread: SendUiUpd: 1608 - рельное время - 1.661
04-17 20:26:39.221 E/Thread: SendUiUpd: 1608 - вис на 223 милисек
04-17 20:26:39.222 E/Thread: SendUiUpd: 1608

Почему обновляет так неравномерно и как исправить это?

Answer 1

Дело в том, что методом Thread.sleep(15) - Вы останавливаете основной поток на 15мс. Советую сделать так: 1) Создать метод

static void sleep(int sleepTime, TimeUnit unitTime){
        try { unitTime.sleep(sleepTime);
        }catch (InterruptedException ignored){}
}

2) Поместить его в Runnable()

new Runnable() {
       @Override
       public void run(){
              sleep(100, TimeUnit.MILLISECONDS)
       }
}

Поток, в котором этим способом будет переопределен в Runnable метод run() будет засыпать на указанное в аргументах количество миллисекунд