These days CPUs with multiple cores have almost become the standard in Android devices. This means multiple operations (could be long running and resource intensive tasks) doesn’t have to wait to be executed on a single thread. They can rather run on multiple threads in parallel where each threads gets executed on a single processor. For example imagine an operation where multiple images have to be downloaded and shown in a gallery view. The downloads and any decoding required for different images could happen concurrently on multiple threads speeding up the entire operation, leading to a faster app experience.
We’ve discussed Services before that run on the application’s UI (main thread). Android provides us with IntentService (extends the
Service class) that has all the properties of a Service’s lifecycle with increased process rank and at the same time allows processing tasks on a background (worker) thread. So using an IntentService you can run long-running operations in the background without affecting the app’s responsiveness and at the same time one of the biggest advantage of it is that, it isn’t affected by most of the user interface (Activity/Fragment) lifecycle events, hence continues to run even when the Activity is destroyed for instance.
The AsyncTask Android class lets us sort of bind background tasks to the UI thread. So using this class, you can perform background operations and then publish the results to the UI thread that updates the UI components. This way you won’t have to deal with threads, handlers, runnables, etc. directly yourself. It’s sort of a helper class around
In this article we’ll try to briefly go through the various sort of low level concepts in Android that are really important to understand IMHO. Once you have a good grasp on these, a lot of things that are actually built atop these concepts become much easier to understand and code. We’ll go through processes, threads, loopers, message queues, messages, handlers, runnables, etc. I’ll also point to various external resources that you should definitely go through for a much better understanding.
Two processes cannot share memory and communicate with each other directly. So to communicate, objects have to be decomposed into primitives (marshalling) and transfered across process boundaries. To do this marshalling, one has to write a lot of complicated code, hence Android handles it for us with AIDL (Android Interface Definition Language). You should read the previous article on the binder framework to get some more idea.
In the Linux OS, there are several techniques to achieve IPC (Inter-process communication) like files, sockets, signals, pipes, message queues, semaphores, shared memory, etc. However, Android’s modified Linux kernel comes with a binder framework which enables an RPC (remote procedure call) mechanism between the client and server processes, where the client process can execute remote methods in the server process as if they were executed locally. So data can be passed to the remote method calls and results can be returned to the client calling thread. It appears as if the thread from the client process jumps into another (remote) process and starts executing in there (known as Thread Migration).
Android has this Loader framework that offers a powerful (yet simple) way to asynchronously load data from content providers or other data sources like an SQLite database, network operation, et al. in an Activity or a Fragment (clients).