Timer(Task) = bad! Do it the Android way: Use a Handler :)

Well, after programming a while for Android I got in touch with some things that are different from usual Java. I already mentioned that before, when I decided to start writing about my experiences with Android: Android & Memory (Leaks) ;)

This time I’d like to write a bit about Timer and TimerTask and why you shouldn’t use them…

While coding for a project I noticed that updating the gui out of a TimerTask didn’t work everytime and specially didn’t work good. Actually it basically never worked and at first I just couldn’t figure what was going on. I put some debugging stuff in the timers and everything seemed to be fine, as the debug messages appeared in the Log. Still: the gui wasn’t affected at all :oogle:
So I started with some research and found a lot of people with same effects but just few answers (kind of get used to that ^^). So after some time I found an article on Android Developers: Updating the UI from a Timer. The author is describing a kind of similar problem to mine but still not the same. Anyway, he’s also talking about “The Android way” which basically says: Timer(Tasks) are bad! Do it the Android way: Use a Handler :) Interesting idea so I gave it a try and now it works perfectly :mrgreen:
I also found some more sources reporting about better performance using handlers and stuff like that (I might look that up again and post some links).

As you can see in the code snippet, it’s pretty easy to go that way too:

First we need a Handler that starts the Runnable after 100ms

private Handler handler = new Handler();
handler.postDelayed(runnable, 100);

And we also need the Runnable for the Handler

private Runnable runnable = new Runnable() {
   @Override
   public void run() {
      /* do what you need to do */
      foobar();
      /* and here comes the "trick" */
      handler.postDelayed(this, 100);
   }
};

So the “trick” is to tell the handler at the end to start the Runnable again. This way the runnable is started every 100ms, like a scheduleAtFixedRate() TimerTask! If you want it to stop, you can just call handler.removeCallback(runnable) and it won’t start again, until you tell it to :thumbup:
There’s also another advantage of this solution: You don’t have to create new Timer(Task)s all the time and can reuse the one Handler and Runnable.

By the way, to get notified about new posts, just enter your email address on the right :)

51 comments

Leave a Reply