How do I manage AsyncTask in Android

Android From Scratch Background Operations

Aside from the most basic Android applications, anything you create requires at least some background threading in order to perform an operation. This is because Android has what is known as ANR (Aapplication Not R.esponsive) Timeout caused when an operation takes five seconds or more on the UI thread, preventing user input and causing the user to appear as a hanging app.

To avoid this, you need to move longer running operations (such as network requests or slow database queries) to another thread to prevent the user from continuing to use your app. Although the full coverage of threading is a large and complex topic in computer science, this tutorial will familiarize you with the core concepts of threading in Android and some of the tools available to help you develop apps that use background processes to produce better results achieve.

Do you find it easier to learn with video? Check out our course:

Understanding threading

When an application starts, a new Linux process is run with a single processMain Execution thread starts. This is the thread that has access to the Android UI toolkit, waits for user input, and handles drawing on the Android device's screen. For this reason, it is also commonly called UI thread

By default, all components of an application run within the same thread and process, although additional threads can be created to move tasks out of the UI thread and prevent an ANR. When it comes to threading in Android, there are two simple rules that need to be followed in order for your app to work as expected:

  1. Do not block the UI thread.
  2. Do not try to access Android UI components from outside the UI thread.

While you can adhere to the first rule by simply creating a new one and, the second rule becomes a little trickier to use. Consider the following snippet of code:

New thread (new Runnable ()) public void run () try Thread.sleep (6000); catch (InterruptedException e) mTextView.setText ("test");). begin ();

While this code does not block the UI thread while the thread is no longer active after the ANR timeout, trying to set the text will cause the app to throw the following error:

android.view.ViewRootImpl $ CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Fortunately, there are a few easy ways you can get around this. You can use Android's method to run the code back on the main thread of the app.

mTextView = (TextView) findViewById (R.id.text); New thread (new Runnable () public void run () try Thread.sleep (6000); catch (InterruptedException e) runOnUiThread (new Runnable () @Override public void run () mTextView.setText ("test"););) . begin ();

Or you can take a standard object and add one to it.

New Thread (new Runnable () public void run () try Thread.sleep (6000); catch (InterruptedException e) mTextView.post (new Runnable () @Override public void run () mTextView.) SetText ("test"); );). begin ();

While these two tricks will help make the thread of your operations safer. The more complex your application becomes, the more difficult it becomes to maintain.

AsyncTask

One of the tools provided by Android for managing complexity with background threads is. provides a worker thread to block operations and sends a result back to the UI thread with a pre-built callback method so that you can easily get your job done without fiddling with threads and handlers.

AsyncTask lifecycle

Before You Begin Using This class, you need to understand the life cycle as compared to performing an operation on the main thread.

The first method called by is. This method runs on the UI thread and is used to set up interface components that need to notify the user that something is happening.

After that finished is called. The generic parameter contains all of the information that you need to pass to the method so that it can perform its task. For example, if you were writing a task that retrieves JSON from a URL, you would pass the URL as a method to that method. Since doing an operation in, you can call to update your user interface (such as an on-screen progress bar). Here the generic value is a value that represents progress, e.g. B. a.

Once the method completes, it can return an object to pass to, just like one that was downloaded from our original url. runs on the UI thread.

When you create a class you have to overwrite these generics in the class declaration as well as in the methods above. An example that updates every second can be seen here:

Protected Class DemoAsyncTask extends AsyncTask

You may have noticed the checks against. This is because there is one big problem with: You maintain a reference to a even after it has been destroyed.

The easiest way to see this is when you start one and then rotate the screen. If you try to make a reference to an article (such as a or) after the original has been destroyed, one is thrown. The easiest way to achieve this is to call your in your or 's and then confirm that the task has not been canceled.

As with any programming process, the answer to when you should use one is: it depends. While they are simple to use, they are not an all-inclusive solution to threading and are best for short operations that take a few seconds or less. If you have an operation that may take longer, I recommend investigating the use of, or (a backward compatible version of the).

Services

When you need to do a long process in the background, such as For example, to play music, conduct network transactions, or interact with a content provider, we recommend that you use a. A basic one can exist in two states: started and limited.

A started is started by a component in your application and remains active in the background of the device even if the original component is destroyed. When the task started is complete, that will stop itself. A standard has started is generally used for long running background tasks that don't need to communicate with the rest of the app.

Abundant is like a started, and it also offers callbacks for various app components that can be tied to it. When all of the bound components have broken away from the, it will stop itself. It's important to note that these two ways of doing a are not mutually exclusive - you can have one that will run indefinitely, and components can be tied to it.

IntentService

One of the biggest problems with a standard that is that it can't handle multiple requests at the same time as it would be a multi-threaded nightmare. One way to do this is to extend an extension, which extends a standard. This creates a standard worker thread for the execution of all intents received in, so all operations can be done outside of the main thread. It then creates a work queue to send each intent to one at a time so you don't have to worry about multi-threading issues.

Apart from the handling of threading, it stops automatically as soon as all start requests have been processed. Because all the implementation details are covered in, the work for you as a developer is pretty straightforward.

public class ExampleIntentService extends IntentService // required constructor with a name for the service. public ExampleIntentService () super ("ExampleIntentService"); @Override protected void onHandleIntent // Do your job here try Thread.sleep (5000); catch (InterruptedException e)

Conclusion

In this tutorial, you learned a lot about threading and multithreading solutions in Android. Entire books were written about threads in Android, but you should now have enough basics to code common tasks and understand more comprehensive documentation for your more complex Android applications down the line.