Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the delay of sleep/timer thread in android during runtime?

What I was trying to do was to decrease the timer delay every time the counter becomes a multiple of 5. But, as soon as the code entered the if block, it stopped incrementing the timer. I can't understand what is happening.

This is the code

thread=new Thread(){
    public void run(){
        try{
            if(count%5==0)
                timre--;
            else{
                //do nothing
            }
            //*******PROGRESS UPDATE********//
            for(t=0;t<=100;t++) {
                sleep((timre) / 100);
                progress.setProgress(t);
                t += 1;
            }
            //****PROGRESS UPDATE OVER****//
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        finally {
            finish();
        }
    }//run ends
};//thread ends
thread.start();//timer starts
like image 491
lordparthurnaax Avatar asked Jun 14 '15 11:06

lordparthurnaax


2 Answers

Threads (and sleep()) are tricky in android. Try using a CountDownTimer instead

CountDownTimer counter;
startTimer();
counter.start();

private void startTimer() {

    counter = new CountDownTimer(4000, 500){

        @Override
        public void onFinish() {

            **DO YOUR STUFF HERE**
        }
        @Override
        public void onTick(long millisUntilFinished) {
        }
    };
}

Call the function startTimer() wherever you want and start the counter at the same time.

like image 182
Amaresh Jana Avatar answered Oct 19 '22 10:10

Amaresh Jana


Thread.sleep() is not guaranteed. This means that it may or may not sleep for the duration you desire for various reasons that are out of topic for this question.

If you search the net for "timer in android" you will probably land on these two: https://developer.android.com/reference/java/util/Timer.html and https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.html

You could check them out, however, I would not use those as they provide a lot of other functionalities as the name suggest ("ScheduledThreadPoolExecutor"). You don't need this as this is most likely to be used for big systems with lots of threads etc...

If I understand your code correctly you are trying to update a progress bar. For what you are trying to do I would suggest using a handler. One of the main uses of a handler is to schedule messages and runnables to be executed as some point in the future as specified in the docs here: http://developer.android.com/reference/android/os/Handler.html

I would do it like this:

 int counter = 0;
 int delayInMs = 5000; // 5 seconds
 Handler timer = new Handler(new Handler.Callback() {

 @Override
 public boolean handleMessage(Message msg) {
   counter++;
   // If the counter is mod 5 (or whatever) lower the delay
   if (counter % 5 == 0) {
     delayInMs/=100; // Or any other calculation.
   } 
   // If the counter reaches 100 the counting will not continue.
   if (counter <= 100) {
     // If the counter has not reached the condition to stop, the handler
     // will call the timer again with the modified (or not) delay.
     timer.sendEmptyMessageDelayed(0, delayInMs);

     // Change progress
     updateProgress(counter);
   }
   return true;
 }
});
// ...

// Somwhere in the code to start the counter
timer.sendEmptyMessageDelayed(0, delayInMs); // starts the timer with the initial 5 sec delay.

One more thing. In the line where you have this code:

progress.setProgress(t);

Be careful when calling UI elements from other threads it is the source of lot of headache. If your handler is in another thread you should wrap that call in a function and make sure it is called from the main thread (i.e. the UI thread). Many ways to achieve that (not always necessary thou). One of them is like this:

private void updateProgress(int counter) {
  WhateverActivity.this.runOnUiThread(new Runnable() {
    public void run() {
      progress.setProgress(counter);
    }
  });
}
like image 27
Aleksandar Apostolov Avatar answered Oct 19 '22 11:10

Aleksandar Apostolov