Natjo
Natjo

Reputation: 2118

Android: UI freezes although use of Handler and postdelay

My app works with a few pictures. I want to take a new one every few seconds and add it to the pictures I work with. So I wrote this code, using an own Thread for the waiting time, so the ui won't freeze.

Handler handler = new Handler();
int time = 500;
for (int cnt = 10000; cnt > 0; cnt -= time) {
     // Execute the code in run after time [ms] passed
     handler.postDelayed(new Runnable() {
         public void run() {
             mainTask();
         }
     }, time);
}

Why does my ui freeze until the for loop ends? Usually the shown pictures should be updated in the mainTask()

Thanks for your help!

[EDIT]

It is working now, I created a class that implements Runnable and let it call itself:

            Handler handler = new Handler();
            class DelayedTask implements Runnable {
                int cnt, time;
                Handler handler;
                DelayedTask(int c, int t, Handler h) {cnt=c; time=t; handler=h;}
                public void run() {
                    mainTask();
                    if (cnt > 0) {
                        cnt -= time;
                        handler.postDelayed(new DelayedTask(cnt, time, handler), time);
                    }
                }
            }
            handler.postDelayed(new DelayedTask(cnt,time,handler), time);

Upvotes: 0

Views: 1164

Answers (2)

nhaarman
nhaarman

Reputation: 100398

You're scheduling 10000/500 Runnables in a very short time, all firing after 500ms, at the same time. This is probably not what you want.

Instead, you want to schedule the next Runnable when the current Runnable fires:

handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    mainTask();

    if(someCondition) {
      handler.postDelayed(this, 500);
    }
  }
}, 500);

Now, mainTask will fire every ~500ms.

Upvotes: 1

qwertz
qwertz

Reputation: 6286

I am not too sure, but I think the handler goes like this:

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            mainTask();
            handler.postDelayed(this, interval);
        }
    }, interval);

Upvotes: 0

Related Questions