There may be situations where you want to spawn a thread from your Activity or Service to handle long running (and may be blocking) tasks. In such cases, its sometimes necessary to pass data back and forth between the main thread and the worker thread(s). E.g. if the worker thread finishes a task and returns the result to the main activity to display the results OR you want to keep a worker thread around and ask it to switch between tasks depending on some message you pass to it.
In the past, I faced some problems understanding these concepts associated with different classes in android.os like the Handler, Looper, HandlerThread etc...
I'll try to explain these concepts in a simple language. Probably most of these explanations are from the developer documentation, but I thought consolidating these at one place may help to get a good picture.
Ok. So, when an application runs, it runs in a Main thread called as the UI thread. Any other thread can be created using the standard java.lang.Thread class. As I said in a typical situation you will spawn a thread, may be pass some data to it OR the thread may pass back some data to the Main thread from time to time as well as when its done executing.
Let us consider the task where we need to send data to a worker thread. So first, we create a worker thread.
STEP 1: Create a worker thread
class MyThread extends Thread {
@Override
public void run(){
}
}
In our main thread...
MyThread mThread = new MyThread();
mThread.start();
When you have to pass any messages to a thread or get messages from a thread, the receiving thread needs a MessageQueue. By default, a thread created by using the java.lang.Thread class will not have a MessageQueue associated with it. Its just a plain old thread as in the Fig. 1 (Yes, I know. What an innovative diagram !! :D ).
Now, we need to attach a MessageQueue to our thread. The Looper class provides the method prepare() to create a message queue for a thread. We need to call this method from the receiving thread's run method.
}
In the past, I faced some problems understanding these concepts associated with different classes in android.os like the Handler, Looper, HandlerThread etc...
I'll try to explain these concepts in a simple language. Probably most of these explanations are from the developer documentation, but I thought consolidating these at one place may help to get a good picture.
Ok. So, when an application runs, it runs in a Main thread called as the UI thread. Any other thread can be created using the standard java.lang.Thread class. As I said in a typical situation you will spawn a thread, may be pass some data to it OR the thread may pass back some data to the Main thread from time to time as well as when its done executing.
Let us consider the task where we need to send data to a worker thread. So first, we create a worker thread.
STEP 1: Create a worker thread
class MyThread extends Thread {
@Override
public void run(){
}
}
In our main thread...
MyThread mThread = new MyThread();
mThread.start();
When you have to pass any messages to a thread or get messages from a thread, the receiving thread needs a MessageQueue. By default, a thread created by using the java.lang.Thread class will not have a MessageQueue associated with it. Its just a plain old thread as in the Fig. 1 (Yes, I know. What an innovative diagram !! :D ).
Now, we need to attach a MessageQueue to our thread. The Looper class provides the method prepare() to create a message queue for a thread. We need to call this method from the receiving thread's run method.
STEP 2: Call the Looper methods
class MyThread extends Thread {
@Override
public void run(){
Looper.prepare();
Looper.loop();
}
As you see, there is one more Looper method called in the code. This loop() method will start running the message loop for the current thread. In simple terms, it will start looking at the MessageQueue and processing the messages. This is how I interpret the Looper as in Fig. 2.
But, who sends the messages to the MessageQueue and how are these processed ? There is a class called the Handler. The Hander allows us to send and process Messages (as well as Runnable Objects) associated with the thread's MessageQueue. So, we need to create a Handler. It is important to note that the Handler is associated with the thread that creates it ! The Handler provides methods to handle (receive) Messages as well as send and schedule messages. For details, please refer to documentation.
STEP 3: Create a Handler to receive the Messages
class MyThread extends Thread {
public Handler mHandler;
@Override
public void run(){
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// Act on the message
}
};
Looper.loop();
}
}
If you notice, this code is the same that is listed on the Looper documentation page here. Few things to mention here are. The Handler is created in this thread, hence it is associated with the default Looper (read MessageQueue) in the current thread. There are constructors for the Handler that allow us to specify the Looper (again, read MessageQueue). This allows us to write a cleaner code by writing the Handler class separately and passing on a Looper (again, again, read MessageQueue) when the Handler is created. I'll get to this in a while. But as I have insisted, it is worth noting that whenever the developer documentation refers to a Looper, you can assume they are talking about a queue. I'm really not sure why they have surfaced the Looper class. It creates more confusion (at least for me). Also, when dealing with passing the messages, with this mechanism, we really need not care of the MessageQueue call. That is the reason I haven't linked it to the documentation. Anyways... things are what they are ! For me, I like to interpret this whole mechanism as depicted in Fig. 3.
Let me know if you like PAT or your way of viewing it !
So, now any other thread having the reference to mHandler will be able to call the send or post methods of the Handler class to send a Message (or a runnable object) to our thread. The code for sending message will look like:
Message msg = Message.obtain();
msg.obj = // Some Arbitrary object
mHandler.sendMessage(msg);
Pretty simple yeah ! Btw, there are various methods to set/get data for the Message object which can be found in the developer documentation for the Message class.
Summary of Steps :
1. Create a Handler in the receiving thread [If it is the main thread, create one in the main thread]. By default the handler will be associated with the default queue (Looper).
2. So, if the receiving thread is created by using java.lang.Thread, then we need to call the Looper.prepare() and Looper.loop() in order to set up the message queue for the thread.
3. In the sending thread, prepare a message object (or a Runnable object)
4. Get a reference to the Handler in the sending thread and call the send/post methods on it to send a message.
HandlerThread:
Since by default java.lang.Thread doesn't contain a message queue (Looper), Android provides a class called as the HandlerThread which already contains a message queue. The only difference in using the HandlerThread class over the method described above is that you need not call the Looper.* methods.
On creation of a HandlerThread, Android will create a thread containing the looper. So, in the main thread the code will look like:
HandlerThread myThread = new HandlerThread("Worker Thread");
myThread.start();
We separately create a Handler as follows:
class MyHandler extends Handler {
public MyHandler(Looper myLooper) {
super(myLooper);
}
public void handleMessage(Message msg) {
}
public void handleMessage(Message msg) {
}
}
}
Now in the main thread, we get the looper for the HandlerThread and pass it when we create the Handler as follows:
Looper mLooper = myThread.getLooper();
MyHandler mHandler = new MyHandler(mLooper);
Whenever we want to send a message from the main thread, we do it in a similar fashion.
Message msg = mHandler.obtainMessage();
msg.obj = // Some Arbitrary object
mHandler.sendMessage(msg);
Thank you very much!
ReplyDeleteThreads are one of throes things there doesn’t appear a lot of (helpful) information on and inter-tread communication is one of throes key things people assume you know.
Anyway I’ve got a couple of quick questions I hope you can help me with.
Firstly, at the foot of your post when you talk about the UI thread getting the looper for the worker thread you has the following code :-
Looper mLooper = myThread.getLooper();
MyHandler mHandler = new MyHandler(mServiceLooper);
Should that be:
Looper mLooper = myThread.getLooper();
MyHandler mHandler = new MyHandler(mLooper);
Or is mServiceLooper declared somewhere else and I’ve missed it?
Secondly am I correct in assuming worker thread can talk to other worker threads (ones they start) in the same way?
Thanks again Scott
@Scott Thanks for the comment.
ReplyDelete1. I'm sorry its a typo. Thanks for pointing it out.
2. Yes, as long as the worker threads have access to the handlers of other threads, they can communicate and this is the preferred mechanism too.
Hope this helps.
Now don't get me wrong, this is a good article, but I fear it unnecessarily confuses two separate ideas: 1) Threads and 2) the Looper/Handler/MessageQueue implementation build on TOP of Java threads. The presentation might be improved by separating these tow ideas.
ReplyDeleteSo, for example, is is simply not true to claim that "When you have to pass any messages to a thread or get messages from a thread, the receiving thread needs a MessageQueue." Why, the whole POINT of the distinction between 'threads' and 'processes' is that threads share address space (therefore global variables) while processes do not. So messages can be passed through globals.
Now of course, globals introduce their own problems, and should be avoided anyway in Object Oriented Programming, whic is what we are usually trying to do in Java in the first place. But I have often seen Android programmers use shared variables like this for very simple message passing. The reader of this article should be prepared for seeing such things too. Even if the article does not recommend imitating such code.
After all, only the very simplest message passing should be done with shared variables: the MessageQueue should be used for more complicated scenarios.
I hope I am not flooding you with too many comments, but it also occurs to me: no discussion of Threads and threading can be complete without mention of the classic problems of multi-threading, data races, deadlock and starvation. These are mentioned briefly and in slightly different language in Oracle's Java Tutorial (thread on concurrency), and also at http://www.cs.duke/edu/~chase/systems/concurrency.html.
ReplyDeleteTo be sure, most of these problems can be avoided by using the MessageQueue, but not all. If the programmer is not thinking about it, he can accidentally design a message-passing scheme that is still liable to deadlock, especially with multiple worker threads.
The classics on these issues, by Birrell and Dijkstra, are still good reading, but their code samples all use pseudo-code based on ancient languages like Modula II and Algol60:( That is why I gave you the Duke University reference instead.
Question: in Step 2, you say, "In simple terms, it [the Looper] will start looking at the MessageQueue and processing the message". Then a little later you say about the Handler that "The Hander allows us to send and process Messages".
ReplyDeleteBut wait! Now we have message processing mentioned as happening in TWO different places. How can this be correct? Is there a difference between the 'processing' that takes place in the Looper, and that that takes place in the Handler methods?
This was never clear in the online Android documentation either, so your readers will thank you even more than they already have if you can make it clear;)
I guess that the handler's handleMessage will be invoked by the Looper on the receiver thread
DeleteThank you for that.
ReplyDeleteIt was also helpful for me.
Do both the sender and receiver need loopers? Or just the receiver?
ReplyDeleteThanks,
Chris.
@Chris, you'll need a Looper only retrieve (receive) messages
ReplyDeleteGreat explanation!
ReplyDeleteBut what if you had an ArrayList that contains custom objects that you have to pass to the main thread?
Let me give an example: you want to show a list of movies to the user, but this is kind of a big list so you'll use a thread to fetch and load the movies.
step 1: address your handler to fetch the movies and make an arraylist of movies (an object that you made yourself, with title, cover, ...)
step 2: returning this list to your UI-thread
step 3: displaying your movies
How would you return this list to your UI-thread? And how do you write your movie class? Do you just make a class with properties and no special interfaces to implement or do you have to implement Parcelable and methods or Serializable?
Thank you in advance :-)
Niels
@Niels, for such complex data, I would suggest you take a look at the REST API design pattern (http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html). This article is mainly for quick and short data. For a large amount of data like the ArrayList that you want, it would be advisable to cache the data. What if the main thread is stopped by the time the worker thread completes its task ? All the effort of fetching and loading the movies will go waste. You will have to redo everything which will be expensive !
ReplyDeleteGreat explanation but I still need a little help to understand how to use this please.
ReplyDeleteIn step 3 the data has been passed to mHandler as 'msg'.
'msg' is a variable in local class mHandler so does not have scope outside mHandler.
So how do I use the data in 'msg' with the MyThread class?
Thank you,
Declan.
THANK YOU!!! I've been searching for some time for a good (in this case, great) explanation. Threads and message queue are finally clear to me. For everything else I can use android docs, but now I understand the principles...
ReplyDeleteCheers!
Newman
Thank You, nice explanation. I have a very basic question here,
ReplyDeleteIam clear in sending message to the thread created by main, but how to communicate back results to main thread from child ?
-regards,
Manju
Manja,
DeleteI believe u need to have a separate msg q (read as Looper) and it's handler object in the main.
--Guru
Excellent. Just what I was looking for.
ReplyDeleteI wonder how this blog was hidden from me for so many days.
Excellent and extraordinary explanation on the concept of threads and loopers, i am really glad to bookmark this blog......:)
ReplyDeleteNice one..........
ReplyDeleteAlso found good tutorial on
Thread_With_Handlers
Nice Thread Tutorial, i am new in android , its help me a lot ...
ReplyDeleteI have got some good links
here at androidexample.com
Thread_With_Handlers
Nice Thread Tutorial, i am new in android , its help me a lot ...
ReplyDeleteI have got some good links
here at androidexample.com
Thread_With_Handlers
Thanks for the posting very useful blog. There is a stack overflow post about an issue which can help developer also. Please check this URL http://stackoverflow.com/questions/4838207/how-to-create-a-looper-thread-then-send-it-a-message-immediately.
ReplyDeleteThanks a lot for posting this post, Your post has always been an informative source for me.
ReplyDeleteandroid training
Thank you for sharing such great information very useful to us.
ReplyDeleteAndroid Training in Noida
Android Training institute in Noida
I am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly..
ReplyDeleteAndroid Training Institute in Noida
Dot Net Training Institute in Noida
ReplyDeleteThanks for sharing this valuable information and we collected some information from this blog.
Android Training in Noida
Good Post. I like your blog. Thanks for Sharing-
ReplyDeleteAndroid Training Institutes in Noida
Thanks for writting such informative articles to help us Noobs :)
ReplyDeletei use the many android mobiles but the HONOR 9C is the best all time and that is provide the best user experience.
ReplyDeleteGood post for more on android free tutorials
ReplyDeleteOk so this doesn't seem to work for me. If I create a handler(handler 1) inside of a worker thread and then create a worker thread(2) and try to write to the first handler I can't access it unless I create a new instance of the thread. Is there not a way to send data to a worker thread without restarting it? I'm lost. Is this a job for Broadcast Receiver? I can't stop and restart my socket connection everytime I want to send it data from my bluetooth connection. How do you access the handler created inside the thread from outside of the thread or from a thread created under it?
ReplyDelete
ReplyDeleteIam so thrilled because of finding your alluring website here.Actually i was searching for Android.Your blog is so astounding and informative too..Iam very happy to find such a creative blog. Iam also find another one by mistake while am searching the same topicIOS Development.Thank you soo much..
You have explained the topic very nice. Thanks for sharing a nice article.Visit Nice Java Tutorials
ReplyDeleteThank you for sharing this wonderful information about Multithreading in Android . Thanks Admin for sharing.
ReplyDeleteNagaqq Yang Merupakan Agen Bandarq terbaik , Domino 99, Dan Bandar Poker Online Terpercaya di asia hadir untuk anda semua dengan permainan permainan menarik dan bonus menarik untuk anda semua
ReplyDeleteBonus yang diberikan NagaQQ :
* Bonus rollingan 0.5%,setiap senin di bagikannya
* Bonus Refferal 10% + 10%,seumur hidup
* Bonus Jackpot, yang dapat anda dapatkan dengan mudah
* Minimal Depo 15.000
* Minimal WD 20.000
* Deposit via Pulsa TELKOMSEL
* 6 JENIS BANK ( BCA , BNI, BRI , MANDIRI , CIMB , DANAMON )
Memegang Gelar atau title sebagai AGEN POKER ONLINE Terbaik di masanya
11 Games Yang di Hadirkan NagaQQ :
* Poker Online
* BandarQ
* Domino99
* Bandar Poker
* Bandar66
* Sakong
* Capsa Susun
* AduQ
* Perang Bacarrat
* Perang Dadu
* BD QQ (New Game)
Info Lebih lanjut Kunjungi :
Website : NAGAQQ
Facebook : NagaQQ official
WHATSAPP : +855977509035
Line : Cs_nagaQQ
TELEGRAM :+855967014811
I want to to thank you for this good read!! I definitely enjoyed every little bit of it. I’ve got you book-marked to look at new stuff you post. 토토사이트
ReplyDeleteIt’s a very easy on the eyes which makes it much more pleasant for me to come here and visit more often.
ReplyDeletemarsbahis
trendbet
galabet
Thank you for sharing such detailed Blog. I am learning a lot from you. Visit my website to get best Information About Best IAS Coaching in Ranchi
ReplyDeleteBest IAS Coaching in Ranchi
Top IAS Coaching in Ranchi
bulk whatsapp sender software provides various features like Unlimited Messages sending, Multi-multimedia message sending, Numbers Filters, Groups Contacts Grabber, Anti Block Module, Sleep Control, Speed control, delay control etc. with In built Google Map Extractor And Just Dial Extractor.
ReplyDelete➡ Our Services:
✅ Website Design & Development
✅ Software Development
✅ Mobile App Development
✅ CRM / ERP Development
✅ Digital Marketing
✅ SEO / SEM / SMM / ASO
✅ Paid Promotion
✅ Graphics & Design
☎ +91 99132 99806 | +91 99132 99862
제천출장안마
ReplyDeleteThanks for this great post.
ReplyDeleteGreat blog. thank you for sharing
ReplyDeleteGreat post.
ReplyDeleteCambridge English Academy gives you the best online ielts coaching in laxmi nagar by highly educated teachers so that you can fulfill your dream of going Abroad In which you also get study material, notes, and extra classes along with the course, for which you do not have to pay any extra charge and contact to go or take a demo
ReplyDeletewebsite = https://www.cambridgeenglish.org.in/
call = 9311441524
수지구콜걸샵
ReplyDelete시흥구콜걸샵
처인구콜걸샵
일산서구콜걸샵
일산동구콜걸샵
영천출장샵
ReplyDelete영주출장샵
포항출장샵
경산출장샵
구미출장샵
Use Bulk whatsApp Sender to Reach your customers at Lighting Speed with Whatso.
ReplyDeleteFeatures:
Grab Contacts from WhatsApp Groups, Fast sending mode, Schedule Sending & Numbers Filter.
thanks for the information.. Matlab Training in Chennai at login360 centers around Matlab as one of the main specialized programming dialects and abilities today.
ReplyDelete전주출장샵
ReplyDeleteMedia Foster is the best SEO company who is known for providing result-oriented white hat & best SEO services at Mohali for all businesses. if you need more information visit our website.김제출장샵
광양출장샵
나주출장샵
목포출장샵
순천출장샵
여수출장샵
Vcare Technical Institute has been providing students with a rich and diverse learning environment. Our unparalleled teaching methods help to launch students into the successful future they have always dreamed of. Vcare Technical Institute is located in Laxmi Nagar, Delhi and has over 100 students and a renowned staff. We encourage both staff and students alike to grow, learn and create each passing day.
ReplyDeleteWe are Provided Various Computer Courses Such as Computer Basic With Advanced, Core java, Advance java, Core PHP, Advance PHP++, Photoshop, Computer Typing and Other Courses. A Computer Course Overview Windows 7 overview, MS Word, MS Excel, MS Power Point, MS Publisher, MS Picture Manager, MS Outlook, MS Access, Basic HTML,
C++ training laxmi nagar Coding classes in Laxminagar , Internet- Search Engines, Email – Account creation, sending and receiving emails, Printing, Scanning, using external Media etc. Excel – creating spreadsheet, Applying formula, pivot table, H lookup, V lookup, filter, freeze, sorting, logical function.
Park View City Lahore is an affordable housing society in Lahore. To get more information about park view lahore check the payment plan.
ReplyDeletePark View City Islamabad Overseas Block contains 5 Marla, 10 Marla, and 1 Kanal residential plot to cater to the ex-pats. We all know that every society builds an overseas block to provide amenities and features at international standards.
ReplyDeleteThe concerned authorities have not revealed the Park View Society Overseas Block location. But according to the sources, it will be announced on 15 July 2022. In addition, it will be situated near the gate, close to the PVC commercial block.
The PVC Islamabad overseas block will have all the facilities, including health, entertainment, and educational institutes, for visitors through a separate gate.
Furthermore, the residents of this block will get a 25% discount on medical and educational charges. The overseas block will also provide Free WI-FI across the area.
인천콜걸마사지
ReplyDelete광주콜걸마사지
대전콜걸마사지
울산콜걸마사지
세종콜걸마사지
경기콜걸마사지
수원콜걸마사지
Online Typing Jobs in Pakistan
ReplyDeleteWhatsApp is one of the most popular messaging apps worldwide, with over two billion users. While it is a powerful tool for personal and business communication, some individuals and organizations have explored the idea of using bulk WhatsApp sender software to send messages to large groups of people simultaneously. In this blog post, we'll discuss what bulk WhatsApp sender software is, its potential risks and benefits, and the ethical considerations that should guide its use.
ReplyDeleteGrowby provides WhatsApp marketing software. Your marketing game will get enhanced 10 times. Moreover, your revenue will increase almost effortlessly.
ReplyDeleteYou can visit here to know more about this software: https://www.growby.net/whatsapp-marketing-software
Having plethora of features, this whatsapp marketing software will effortlessly help you contact your customers via whatsapp. the marketing channel which has a huge user base and is easily accessible by users all around the world
ReplyDeleteThis information is so impressive. Thanks for sharing it.If you are interested in Technical Stuff vist our Site VLSI Training in Bangalore for more info.
ReplyDelete