Start objects faster and update Textview faster

Viewed 164

I want to create multiple timers. I initialize this in an ArrayList in the MainActivity. These are then added in a ReyclerView so that they are also displayed. To start, I go through a for loop and execute the startTimer () method for each individual object. Unfortunately, the times are not correct for every timer. That means one timer is faster, the second is slower and so on. So each timer starts at different times or the text changes at different times.

My question now is, are there other approaches to start the timers and change the texts in the TextView so that the GUI is updated faster and the program itself runs faster? The goal should be that all timers are equally fast and there is no delay. Thanks in advance. Looking forward to answer!

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

Timer

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 Answers

Use Live Data and Binding or MVVM design pattern. You don't have to worry about faster update operation of views.

The reason the code you wrote works slowly (and time isnt updated on all views together), is because you are creating a separate CountDownTimer for each of your timers.

You dont have to do that. All you need to do is have a single CountDownTimer, that runs every second and updates all of your views simultaneously.

  1. Make Timer class only store the start time of the timer, and a string with the time it should show, dont create a CountDownTimer inside it.

    Instead create a method inside it - "updateTimer()" for updating the string, based on the current time and the start time of the counter.

  2. Using a single CountDownTimer in your Activity, loop through the list of timers and call updateTimer() on each of your timers, and call adapter.notifyDataSetChanged() when the loop is done.

This will make all your views update together, remove the inefficiency of using multiple CountDownTimers, and only call adapter.notifyDataSetChanged() once every second (as opposed to the amount of timers you have - every second)

i think the main issue is the sequential executing of instructions, and adding Threads concept may resolve the issue ,what i think is Threads and Multi threading will allow timers to start at the same time and any updates or other instructions of code execution will not effect the already running code .

Multi threading refers to two or more tasks executing concurrently within a single program. Tutorial

now To start the threads at exactly the same time (at least as good as possible),we can use a 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

                 };

This still can't make sure that they are started exactly at the same time on standard JVMs, but you can get pretty close.

replicate the same solution if it works , for the update part

Related