Over a million developers have joined DZone.

Fixing the NetworkOnMainThread Exception in Your Android App with AsyncTask

DZone 's Guide to

Fixing the NetworkOnMainThread Exception in Your Android App with AsyncTask

We take a look at how to handle a common but pesky scenario involving your Android app performing long-running tasks. Read on for some insight and ideas!

· Mobile Zone ·
Free Resource

As soon as you start doing long-running operations such as network calls or anything else that can take more than a few seconds in your Android application, you’ll come across one of the following problems:

  • The [Application] not responding (ANR) popup is shown while you run your application, and the The application may be doing too much work on its main thread warning is shown in your Logcat traces.
  • The NetworkOnMainThreadException exception is launched as soon as you call anything over the network like an API, regardless of the duration of the call.

Why does the Android SDK complain when one of those things happens? Why does code that seems to be correct not work? Well, if your application stays frozen, your users could think it crashed. A few seconds is an eternity when you don’t have any feedback about what’s going on, and users are probably going to keep pressing buttons as a response, or close your application and never return. So, to prevent this, the Android SDK enforces minimum standards for responsiveness and display errors if those standards are not respected.

To understand why the application freezes, we must take a look at the architecture of the application. By default, your Android application has only one thread, called the main thread. All your code will execute on this single thread, and a thread can only do one thing at a time.

So, if you call the network and there is a delay, everything stops while the application waits for an answer, freezing your UI completely. You won’t even be able to display a progress bar because nothing else can run. The timeline looks like:

Image title

Fortunately, you can create new threads, which allow you to do more than one thing at once:

Image title

For one-time operations that only take a few seconds, the easiest way to manage this is to use the AsyncTask class available in the Android SDK. It will create a new thread for you that will do a specific task, and then notify you when that task is over so you can update your UI.

Here is an example of an AsycTask that calls the GitHub API to calculate the number of repositories that contain the “Android” string. While the query is running, a progress bar is shown in the UI.

private class GithubAndroidRepositoryQueryTask extends AsyncTask<String, Integer, String> {

protected void onPreExecute() {
   // Prepare the UI in the main UI thread before executing the task.

protected String doInBackground(String... params) {
   // Do the operation on a new thread and returns the result. It calls the GitHub API to 
   // calculate the number of repository that contains the Android string
   return getAndroidRepositoryCountFromGitHub();

protected void onProgressUpdate(Integer... progress) {
   // Could be used to update the main UI thread with the progress of the background
   // operation.

protected void onPostExecute(String result) {
   // Receive the result of the operation done in the new thread in the main UI thread and
   // use it to update the UI.

And here is how you execute that task. In that case, it’s launched an onCreate event of the Activity so the response is visible immediately in the layout, but it could be launched from anywhere else:

public class MainActivity extends AppCompatActivity {

protected void onCreate(Bundle savedInstanceState) {
   mGitRepositoryTextView = (TextView) this.findViewById(R.id.github_repositories_tv);
   mGitRepositoryProgressBar = (ProgressBar) this.findViewById(R.id.github_repositories_pb);

   // Fires off an AsyncTask to get the number of Android repositories on GitHub and displays
   // it in the application.
   new GithubAndroidRepositoryQueryTask().execute();

Success! Now check your email to confirm your subscription and get your executable code sample.

When you’re working with threads of any kind, remember that updating the UI should only be done on the main thread. The Android SDK doesn’t support updating the UI from other threads, so you’ll likely have random crashes and weird behavior if you attempt it.

Also, as a caveat, Google doesn’t recommend relying on showing a progress bar exclusively for long-running operations. They believe that users should be able to keep working in the application and that you should manage what’s going on in the backend.

If you have a simple application that has only a few simple cases it may work, but if you have complex interactions between your data you can sink a lot of time trying to make everything work nicely together and handling what happens if an operation fails.

Still, you can start with a simple AsyncTask and optimize as you go along. In most cases, it’s going to be a good starting point, but as soon you need to execute many tasks at once it won’t be enough. When you’re ready to go further with this, you should take a look at libraries such as RxJava to help you manage your tasks.

android ,mobile ,application development

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}