Search code examples
androidandroid-handler

handler.postdelayed() milliseconds automatically changes after activity onResume()


i'm using simple progressBar in my app with handler.postdelayed to change bar value (constant time) and initial bar value is 100.

Handler progress_handler;
Runnable runnable;
ProgressBar bar;
int progress;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bar= (ProgressBar) findViewById(R.id.progressBar);
    progressBar();
}

private void progressBar()
{
    progress_handler = new Handler();
    runnable = new Runnable()
    {
        @Override
        public void run() {

            progress=bar.getProgress();
            if(progress<=0)
            {
                progress_handler.removeCallbacks(runnable);

            }
            else {
                bar.setProgress(progress - 1);
                progress_handler.postDelayed(runnable, 50); // 50 milliseconds here 

            }
        }
    };
    // Start the Runnable immediately
    progress_handler.post(runnable);

}

this is working perfect but the problem happens when i pause and resume the activity

 @Override
protected void onPause() {
    super.onPause();
    progress_handler.removeCallbacks(runnable);
}

protected void onResume() {
    super.onResume();
    progress_handler.post(runnable);
}

now the progress bar speed is not 50 milliseconds as i set it is slower .. what happened ?


Solution

  • If you want your progress to keep decreasing, you need to use a Timer instead of a Handler

    Timer.scheduleAtFixedRate(TimerTask task, long delay, long period)
    

    Where task is basically your Runnable

    You can create everything in onCreate, and in the activity's onResume() call scheduleAtFixedRate and call cancel in onPause

    However, this runs your code on a background thread, so you man need a Handler to post data on UI thread, or use runOnUiThread of the activity.

    Another option would be using Android's CountDownTimer

    A third option would be to remove extra call to handler.post in onCreate, only keep one in onResume