Запускайте объекты быстрее и быстрее обновляйте Textview - PullRequest
6 голосов
/ 05 августа 2020

Я хочу создать несколько таймеров. Я инициализирую это в ArrayList в MainActivity. Затем они добавляются в ReyclerView, чтобы они также отображались. Для начала я go через a для l oop и выполняю метод startTimer () для каждого отдельного объекта. К сожалению, время подходит не для каждого таймера. Это означает, что один таймер быстрее, второй медленнее и так далее. Таким образом, каждый таймер запускается в разное время или текст изменяется в разное время.

Теперь у меня вопрос, есть ли другие подходы для запуска таймеров и изменения текстов в TextView, чтобы GUI обновлялся быстрее а сама программа шустрее работает? Цель должна заключаться в том, чтобы все таймеры работали одинаково быстро и без задержек. Заранее спасибо. С нетерпением жду ответа!

MainActivity

     timerList= new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            timerList.add(new Timer(i, 600000 * i))); // 
Each timer has a different time
        }
    
        recyclerView.setLayoutManager(recyclerViewLayoutManager);
        adapter = new TimerAdapter(this, timerList);
    
        recyclerView.setAdapter(adapter);
        context = this;
    
    
        button_start.setOnClickListener(v -> {
    
                for (Timer timer: timerList) {
                    timer.startTimer();
                
    
        });
    
    @Override
    public void updateMyText(int index, long time) {
        timerList.get(index-1).setTime(time);
        adapter.notifyDataSetChanged();
    }

Таймер

public interface MyCallback {
    public void updateMyText(int index, long time);
}
   public Timer(int index, long startTimeMilliseconds) {
        this.index = index;
        this.time = startTimeMilliseconds;
        mTimeLeftInMillis = startTimeMilliseconds;
        startTime = startTimeMilliseconds;
    }



    public void startTimer() {
        mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }
            @Override
            public void onFinish() {
                mTimerRunning = false;
            }
        }.start();
        mTimerRunning = true;
    }

    public void resetTimer() {
        mCountDownTimer.cancel();
        mTimerRunning = false;
        mTimeLeftInMillis = startTime;
        timeLeftFormatted = formattedTime(startTime);
        changeText(index-1);
    }

    public void updateCountDownText() {
        //MainActivity.timerList.get(getIndex()-1).setTime(mTimeLeftInMillis);
        //MainActivity.adapter.notifyDataSetChanged();
        if(myCallback != null) {
            myCallback.updateMyText(getIndex(), mTimeLeftInMillis);
        }
    }

Ответы [ 3 ]

2 голосов
/ 06 августа 2020

Используйте Live Data and Binding или шаблон проектирования MVVM. Вам не нужно беспокоиться о более быстром обновлении представлений.

1 голос
/ 16 августа 2020

Я думаю, что основная проблема заключается в последовательном выполнении инструкций, и добавление концепции Threads может решить проблему, то, что я думаю, Threads и Multi threading позволит таймерам запускаться одновременно и любым обновлениям или другие инструкции выполнения кода не повлияют на уже запущенный код.

Многопоточность относится к двум или более задачам, выполняемым одновременно в рамках одной программы. Tutorial

now Чтобы запускать потоки в одно и то же время (по крайней мере, как можно лучше), мы можем использовать CyclicBarrier :

 // We want to start just 10 threads at the same time, but let's control that 
 // timing from the button_start click thread. That's why we have 11 "parties" instead 
 //of 10.
 final CyclicBarrier gate = new CyclicBarrier(11);
 button_start.setOnClickListener(v - > {
             for (Timer timer: timerList) {
                 new Thread() {
                     public void run() {
                         gate.await(); // waiting for the gate to open
                         timer.startTimer();
                     }
                     // At this point, all the 10 timers are blocked on the gate. 
                     // Since we gave "11" as the argument, gate is not opened yet.
                     // Now if we block on the gate from the main thread, it will open
                     // and all threads will start to do stuff!

                     gate.await(); // this is the extra 11th which will open the gate

                 };

Это все еще не может гарантировать, что они запускаются точно в одно и то же время на стандартных JVM, но вы можете подойти довольно близко.

реплицировать то же решение, если оно работает, для обновления часть

1 голос
/ 14 августа 2020

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

Вам не нужно этого делать. Все, что вам нужно сделать, это иметь один CountDownTimer, который запускается каждую секунду и обновляет все ваши представления одновременно.

  1. Заставить класс Timer хранить только время начала таймера и строку со временем, которое должно отображаться, не создавайте внутри него CountDownTimer.

    Вместо этого создайте внутри него метод - «updateTimer ()» для обновления строки на основе текущего времени и времени начала счетчика.

  2. Используя один CountDownTimer в своей деятельности, l oop просматривает список таймеров и вызывает updateTimer () для каждого из ваших таймеров, а также вызывает adapter.notifyDataSetChanged (), когда l oop готово.

Это заставит все ваши представления обновляться вместе, устранит неэффективность использования нескольких CountDownTimers и вызовет адаптер.notifyDataSetChanged () только раз в секунду (в отличие от количество имеющихся у вас таймеров - каждую секунду)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...