Android AsyncTasks Basics

This article covers the difference in threads and Asyncs, using Asyncs, stopping them, and avoiding memory leaks associated with them.

The basic idea of why Android released Asynctasks was to perform non-UI tasks on worker threads, and leaving the UI tasks for important stuff(UI rendering) only. But what was the need? Why can't we have used java Threads only?

UI thread in Android:

So say if the UI thread is doing some extensive work, and it does not get the time to render UI within that window, the user will see the lag in the application. And furthermore if the UI is not rendered for 5 seconds, then the Application will crash with the ANR error: Application not responding.

Nobody would like this. So its the best to let UI thread be responsible only to render the UI, and move other tasks to other threads, which will do the work and reply back to UI thread once work is done. And then UI thread can show the status of that work or act accordingly.

The issue with Java Threads in Android architecture

And this is not an issue, as that 7 seconds’ work is delegated to the worker thread. The logs are:

And this is what we desire.

What are the issues associated with this?

  1. We can't update the UI from the Thread directly. For example:

This throws the following error:

2. The configuration changes can’t be handled from the Threads. These are tied to the Main threads, and other threads are not notified by android about these changes.

3. Canceling/stopping the normal threads is not very elegant.

Async tasks usage:

So it provides clarity on how the code is run.

AsyncTask will go through the following 4 stages:
1. onPreExecute()
Invoked on the UI thread before the task is executed
2. doInbackground(Params..)
Invoked on the background thread immediately after onPreExecute() finishes executing.
3. onProgressUpdate(Progress..)
Invoked on the UI thread after a call to publishProgress(Progress…).
4. onPostExecute(Result)
Invoked on the UI thread after the background computation finishes.

Any attempt to update UI inside DoInBackground will throw the similar exception:

But we can update the UI from onPreExecute and onPostExecute:

Canceling Async task:

Example 1- task: Sleep the thread

So the doInBackground which should run for 7 seconds, will be stopped in between by UI thread after 2seconds.

So DoInBackground was interrupted(which in turn called thread inside Async to interrupt, which flowed down to Thread.sleep to interrupt).
But after this, the log after sleep() is still printed.
So can't make out from this if the doInBackground was doing its work or not after it was canceled.

Example 2: Task- increment count which usually takes 6–7 seconds to run:

This is the perfect example to understand the behavior.
So after the Async was canceled only after 2 seconds, we see the DoInBackground was still doing its work. The task at log was printed at 55. So is the cancel method not doing its work?
Well, partially.
To understand more in detail: Go to its internal implementation at https://tinyurl.com/y4h5bua4.

Example 3- Correct way to cancel the Async:

The cancel method will not stop the doInbackground to stop its execution, but it will only set a boolean true. We ourselves need to stop its execution using that boolean. This can be done like:

So isCancelled() is the one we need to use wisely.

So doInBackground did not continue to run after 2 seconds, as per the logs. Good.

Configuration changes and Async Tasks:

The Activity will start the Async(which takes 5 sec to complete), and before that the screen will be rotated. To differentiate between the Async logs, lets print the hashcode of various activities.

If we see the logs:
Activity- 8483517 started, which started the Async.
The screen was rotated before the task could complete.
Its Async task was still running.

51491206 the new Instance of that activity created, which launched new ASync.
Later on, we see “8483517" task completed. Meaning that it was still running, and holding the instance of the activity- which is a potential memory leak.

Solving memory leaks:

Backend/Android Developer | https://www.linkedin.com/in/anmol1410/