Note : Here are my two tutorials on Android Concurrency Model. Please have a look at these:
In the part - I of the discussion on concurrent programming in Android, we have seen about the Handler-Message-Runnable & Asynchronous task framework. There we took a case study of downloading an image from an Internet server and found out how these methodologies can be applied for a long running task which has to be done in a background thread.
With the continuation of the same discussion we will today talk about the internals of the Android Concurrency Model - particularly about the topics like Looper, Message Queue, Handler and and how they work together to give us a better concurrent system. We will also develop an example in which we will pass a message from the main UI thread to a background worker thread immediately after the worker thread is created. We will also see the usefulness of the Java Synchronization technique, specifically the CountdownLatch synchronization object.
Here is a simplified diagram of Asynchronous Model of Android which shows how we can post Runnables or send Messages through Handler to the MQ of the Looper.
At the heart of any UI driven model, lies a loop called Message Loop whose task is to listen to any hardware events that the user may generate and dispatch them to the appropriate handler. In android this message looping is done by a class called Looper. The simpler version of the Looper class is as follws:
}
Important function of Looper is prepare.
As we can see from the above code that the prepare function actually constructs the Message Queue responsible for queuing up messages. Also in the prepare function we can see that there will be only one looper per thread. The looper gets stored as a Thread Local Storage object. And as we can see, the thread in which the Looper.prepare is called, becomes the looper's mThread object.
The other important function of the Looper class is the loop method. It has been defined as follows:
Have a look infinite for loop and the following dispatchMessage method. This is what is responsible for listening events and dispatching those messages to the right handler.
Next important Class is the Handler class. The bare minimal version of this Handler class is as follows:
The handler class is a utility class and is responsible to help users to send messages to the Message queue. If we take the current thread's Handler to send message, the messages will be posted to the current thread's looper's Message Queue.
The main thread or the UI thread of Android will automatically have a looper. But if we want to create an worker thread, we need to specifically add the Looper for that thread. The below code is an example of such an worker thread. Lets call it as LooperThread.
As we can see from the above code snippet, the moment we declare the above piece of code in any Android worker thread, it becomes capable of handling incoming messages.
Its all theories. Now lets write an example of sending messages from the UI thread of Android (or Activity) to a background thread. You can download the source code from here
The WorkerThread class is defined as follows:
And the MainActivity from where the message is sent to the WorkerThread is defined as follows:
This is simple. Only one issue that i would like to discuss about that to avoid the Race Condition, i have used the Java Synchronization object CountdownLatch. For this countdownlatch, we send the message only when the worker thread becomes ready.
Hope i am able to throw some lights on the internals of Android Concurrency Model.
In the part - I of the discussion on concurrent programming in Android, we have seen about the Handler-Message-Runnable & Asynchronous task framework. There we took a case study of downloading an image from an Internet server and found out how these methodologies can be applied for a long running task which has to be done in a background thread.
With the continuation of the same discussion we will today talk about the internals of the Android Concurrency Model - particularly about the topics like Looper, Message Queue, Handler and and how they work together to give us a better concurrent system. We will also develop an example in which we will pass a message from the main UI thread to a background worker thread immediately after the worker thread is created. We will also see the usefulness of the Java Synchronization technique, specifically the CountdownLatch synchronization object.
Here is a simplified diagram of Asynchronous Model of Android which shows how we can post Runnables or send Messages through Handler to the MQ of the Looper.
At the heart of any UI driven model, lies a loop called Message Loop whose task is to listen to any hardware events that the user may generate and dispatch them to the appropriate handler. In android this message looping is done by a class called Looper. The simpler version of the Looper class is as follws:
}
Important function of Looper is prepare.
As we can see from the above code that the prepare function actually constructs the Message Queue responsible for queuing up messages. Also in the prepare function we can see that there will be only one looper per thread. The looper gets stored as a Thread Local Storage object. And as we can see, the thread in which the Looper.prepare is called, becomes the looper's mThread object.
The other important function of the Looper class is the loop method. It has been defined as follows:
Have a look infinite for loop and the following dispatchMessage method. This is what is responsible for listening events and dispatching those messages to the right handler.
Next important Class is the Handler class. The bare minimal version of this Handler class is as follows:
The handler class is a utility class and is responsible to help users to send messages to the Message queue. If we take the current thread's Handler to send message, the messages will be posted to the current thread's looper's Message Queue.
The main thread or the UI thread of Android will automatically have a looper. But if we want to create an worker thread, we need to specifically add the Looper for that thread. The below code is an example of such an worker thread. Lets call it as LooperThread.
As we can see from the above code snippet, the moment we declare the above piece of code in any Android worker thread, it becomes capable of handling incoming messages.
Its all theories. Now lets write an example of sending messages from the UI thread of Android (or Activity) to a background thread. You can download the source code from here
The WorkerThread class is defined as follows:
And the MainActivity from where the message is sent to the WorkerThread is defined as follows:
This is simple. Only one issue that i would like to discuss about that to avoid the Race Condition, i have used the Java Synchronization object CountdownLatch. For this countdownlatch, we send the message only when the worker thread becomes ready.
Hope i am able to throw some lights on the internals of Android Concurrency Model.
No comments:
Post a Comment