Better Programming

Advice for programmers.

Follow publication

Drift Away From Android Handlers. Use Coroutines and Jobs Instead!

Timed tasks can be simplified using Coroutines and Jobs over a Handler. See how!

Dhanesh Katre
Better Programming
Published in
2 min readMar 28, 2022
Drift away from Handler, use Coroutines and Jobs instead!

Scenario

We all have used Handlers with postDelayed method to perform some task after a certain time duration in our Android applications. That was our go-to way for performing tasks with such kind of time requirements.

Using a Handler, a typical code to perform a task after 10 seconds would look like this:

I think this is tedious!

The creation and maintenance of a Handler instance especially become tedious when there’s a scope that asks us to cancel the currently running timed task and we have multiple tasks running at the same time.

In this case, we’d have to maintain either a token or separate runnable instance for canceling the desired task in between, before the timer elapses.

Also, the provision of a Looper instance for Handler’s creation may seem a bit tedious and most of us tend to just use the default main looper (used in the above gist) which again causes some UI issues / Janks, etc.

Enter Coroutines and Jobs

Thanks to the Kotlin Coroutines and Jobs mechanism, we can get away from using Handlers in this scenario, by creating lightweight Coroutine Jobs and cancelling them in between to just stop the desired task from getting executed.

The above code using a Coroutine Job would look like this:

Instead of maintaining 2 separate instances of Handler and a runnable, we can maintain only 1 instance of a Job.

Whenever we want to start a task, that executes after X seconds (10 seconds in this case) we can just cancel previously running job instance (this is optional, just to avoid inconsistent states) and create a new Job instance and get the reference of it.

The delay method used in the Job will suspend the task for X seconds (10 seconds in this case) and then resume the execution after it. And if we want to cancel the task in between, we can just cancel the Job! Pretty clean and simple, isn’t it?

Since Coroutines and Jobs are considered lightweight, creation of new Jobs each time won’t have any significant impact on performance. We can also use the desired dispatcher (for example, Dispatchers.IO) to perform the task on, so no need of providing a fixed Looper instance as in the case of a Handler, making code more thread-friendly and with lesser bugs!

Though Handler has its own use cases, we can surely use Coroutines and Jobs over it, for performing timed tasks in a neat manner.

What do you think about this approach? Would you like to improve it furthermore? Anything that you’re concerned about?

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Responses (3)

Write a response