HandlerThread thread = new HandlerThread("DownloadService");
thread.start();
Is the looper associated with the thread waiting for a message to arrive in the message queue just after thread.start() returns? If so, then all I need to do is to associate the looper of this thread with a class that implements handleMessage(). Would this be the correct implementation?
Is the looper associated with the thread waiting for a message to arrive in the message queue just after thread.start() returns?
Not necessarily. start() only creates a thread that will --at some point in the future-- create a Looper. start() itself does not wait for the looper to be ready.
Edit: However, this usually is not a problem, since HandlerThread.getLooper() will wait for the looper to be properly prepared if it is not yet ready.
Side note: I think HandlerThread is not a well named class, since it actually only creates a Looper.
Related
Is a Handler a Thread or not? If yes, how can we update the UI from this Handler(thread)?
If we use the Looper concept, it may be possible. In this case, does it apply to any threads? I am very much confused about these Threads, Handlers and Loopers. Could anyone please explain them with an example?
Is a Handler a Thread or not? If yes, how can we update the UI from this Handler(thread).
If we use the Looper concept, it may be possible, in this case does it apply to any threads? I am very much confused about this Thread, Handler and Looper. Could anyone please explain them with an example?
The question "What is the difference between a Thread and a Handler" is only about Handlers and Threads, but does not explain Loopers and their behavior. And the accepted answer says that "Handlers on the other hand are background threads that allow you to communicate with the UI thread (update the UI)", but according to the answer by "ben75" below, a Handler is not a Thread. Thus, I do not think this is a duplicate of that question.
premise : A Handler is not a Thread.
A Looper is an Object associated with the Thread from which it is created. As you can guess by it's name a Looper is going to loop over something, but looping over what ? Over a message queue also associated with the same thread.
Next question is: How can I put something in this message queue ?
And here is the Handler. A Handler is always associated with a Looper (which one ? we will see it later). The Handler can play 2 roles (and that's maybe why it is confusing)
First role of the Handler : you must use it to post messages to it's associated Looper (in fact to it's message queue). You can use one of the various Handler.sendMessage* (or Handler.post*) methods to do that. (and note the sendMessageDelayed/postDelayed methods allowing you to post a Message/Runnable to be handled in future)
What is the Looper associated with a Handler ? Very easy : the Looper of the current Thread if you don't specify it; but you can use the constructor with a Looper : new Handler(Looper looper) and in this case the handler is associated with looper in argument.
At this point, we know that :
a Looper is associated with one and only one Thread
a Looper loops over it's associated message queue
as a consequence : there is one message queue associated with one Thread (as soon as we have a Looper for the Thread)
a Handler is always associated with one Looper
a Handler can be used to post message to the message queue
Now, let's see the second part : the message processing/message handling.
First, let's look at the Looper looping over it's message queue.
Is there is a message in the queue ? Yes (i.e. at some point, a Handler has posted it.)
Is it time to handle this message (if it was posted with postDelayed) ? If not, wait a little. If it is time : let's dispatch this message.
Remember that I told that the Handler have 2 roles... and here is the second role of the Handler : a Handler (as indicated by it's name) can handle messages. To be able to handle custom messages you must subclass the Handler class and implements the handleMessage(Message) method.
So, the Looper will simply call the handleMessage of the Handler who posted the message and it's job (i.e. dispatching the messages) is finished (the Looper can move on to the next Message in the queue).
At this point you may ask yourself : "OK I see the interest of delayed messages, but why should I use all this stuff for things to do immediatelly ?"
Remember that the Looper is associated with one Thread and the handleMessage will be called in this Thread. On the other hand, the Handler.post* can be called from another thread. So this mechanism is also very convenient to schedule a job in thread X from thread Y. (particularly useful if the job is affecting the UI and MUST be run in the UI-Thread)
Final note
UI-thread is a first class citizen :
On Android, there is a main Looper associated with the main Thread (i.e. the UI-thread). You can get a reference to it with Looper.getMainLooper(), so you create a Handler associated with the main Looper with :
Handler myHandler = new Handler(Looper.getMainLooper());
and with that you can post a message from any thread to the UI-thread
Should you really use messages and subclassing Handler to use this ? No (not always)
You don't always need to create message explicitly to use this mechanism. You can easily post a Runnable to a Handler and in this case you don't even need to override the handleMessage(Message) because the default implementation of the Handler will simply execute the Runnable (under the hood : a message is created with the Runnable associated to it)
Looper must be prepared (to receive messages)
By default there is no Looper on every thread (by default, there is only a prepared one in the UI-Thread). To prepare a Looper for the current thread : call Looper.prepare()
Handler:
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue. Each Handler instance is
associated with a single thread and that thread's message queue. When
you create a new Handler, it is bound to the thread / message queue of
the thread that is creating it -- from that point on, it will deliver
messages and runnables to that message queue and execute them as they
come out of the message queue.
Now,if you want to update the UI from some other thread that is not the main thread, you will first create a Handler in the main thread and pass it onto any background thread. In the background thread you would do use the post (Runnable r) method to send the message back to the main thread because (read the above paragraph) :) Handlers are not threads, though.
Thread:
A thread is a thread of execution in a program.
Just a generic background processing task.
Looper:
Looper is a class which is used to execute the Messages(Runnables) in
a queue. Normal threads have no such queue, e.g. simple thread does
not have any queue. It executes once and after method execution
finishes, the thread will not run another Message(Runnable).
Sources:
What is the purpose of Looper and how to use it?
What is the difference between a Thread and a Handler
I know a handler is bound to the thread's message queue in which it is created, but what if i create a handler in a service and posting a runnable declared in activity to which my service is bound.
For example:
In service:-
Handler handler=new Handler();
handler.post(Mainactivity.runnable);
In activity inside oncreate method:-
Runnable runnable=new Runnable(){
public void run{
//some code here
}
};
Can someone please explain me what's happening here?
Please find information about Message Queue and Looper in below link
Understanding Android Core: Looper, Handler, and HandlerThread
In the Android via Looper, Handler, and HandlerThread. The System can be visualized to be a vehicle as in the article’s cover.
1.MessageQueue is a queue that has tasks called messages which should be processed.
2.Handler enqueues task in the MessageQueue using Looper and also executes them when the task comes out of the MessageQueue.
3.Looper is a worker that keeps a thread alive, loops through MessageQueue and sends messages to the corresponding handler to process.
4 Finally Thread gets terminated by calling Looper’s quit() method.
By default service will run on UI Thread. So the handler you create on service will post the runnable on UI Thread
Is a Handler a Thread or not? If yes, how can we update the UI from this Handler(thread)?
If we use the Looper concept, it may be possible. In this case, does it apply to any threads? I am very much confused about these Threads, Handlers and Loopers. Could anyone please explain them with an example?
Is a Handler a Thread or not? If yes, how can we update the UI from this Handler(thread).
If we use the Looper concept, it may be possible, in this case does it apply to any threads? I am very much confused about this Thread, Handler and Looper. Could anyone please explain them with an example?
The question "What is the difference between a Thread and a Handler" is only about Handlers and Threads, but does not explain Loopers and their behavior. And the accepted answer says that "Handlers on the other hand are background threads that allow you to communicate with the UI thread (update the UI)", but according to the answer by "ben75" below, a Handler is not a Thread. Thus, I do not think this is a duplicate of that question.
premise : A Handler is not a Thread.
A Looper is an Object associated with the Thread from which it is created. As you can guess by it's name a Looper is going to loop over something, but looping over what ? Over a message queue also associated with the same thread.
Next question is: How can I put something in this message queue ?
And here is the Handler. A Handler is always associated with a Looper (which one ? we will see it later). The Handler can play 2 roles (and that's maybe why it is confusing)
First role of the Handler : you must use it to post messages to it's associated Looper (in fact to it's message queue). You can use one of the various Handler.sendMessage* (or Handler.post*) methods to do that. (and note the sendMessageDelayed/postDelayed methods allowing you to post a Message/Runnable to be handled in future)
What is the Looper associated with a Handler ? Very easy : the Looper of the current Thread if you don't specify it; but you can use the constructor with a Looper : new Handler(Looper looper) and in this case the handler is associated with looper in argument.
At this point, we know that :
a Looper is associated with one and only one Thread
a Looper loops over it's associated message queue
as a consequence : there is one message queue associated with one Thread (as soon as we have a Looper for the Thread)
a Handler is always associated with one Looper
a Handler can be used to post message to the message queue
Now, let's see the second part : the message processing/message handling.
First, let's look at the Looper looping over it's message queue.
Is there is a message in the queue ? Yes (i.e. at some point, a Handler has posted it.)
Is it time to handle this message (if it was posted with postDelayed) ? If not, wait a little. If it is time : let's dispatch this message.
Remember that I told that the Handler have 2 roles... and here is the second role of the Handler : a Handler (as indicated by it's name) can handle messages. To be able to handle custom messages you must subclass the Handler class and implements the handleMessage(Message) method.
So, the Looper will simply call the handleMessage of the Handler who posted the message and it's job (i.e. dispatching the messages) is finished (the Looper can move on to the next Message in the queue).
At this point you may ask yourself : "OK I see the interest of delayed messages, but why should I use all this stuff for things to do immediatelly ?"
Remember that the Looper is associated with one Thread and the handleMessage will be called in this Thread. On the other hand, the Handler.post* can be called from another thread. So this mechanism is also very convenient to schedule a job in thread X from thread Y. (particularly useful if the job is affecting the UI and MUST be run in the UI-Thread)
Final note
UI-thread is a first class citizen :
On Android, there is a main Looper associated with the main Thread (i.e. the UI-thread). You can get a reference to it with Looper.getMainLooper(), so you create a Handler associated with the main Looper with :
Handler myHandler = new Handler(Looper.getMainLooper());
and with that you can post a message from any thread to the UI-thread
Should you really use messages and subclassing Handler to use this ? No (not always)
You don't always need to create message explicitly to use this mechanism. You can easily post a Runnable to a Handler and in this case you don't even need to override the handleMessage(Message) because the default implementation of the Handler will simply execute the Runnable (under the hood : a message is created with the Runnable associated to it)
Looper must be prepared (to receive messages)
By default there is no Looper on every thread (by default, there is only a prepared one in the UI-Thread). To prepare a Looper for the current thread : call Looper.prepare()
Handler:
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue. Each Handler instance is
associated with a single thread and that thread's message queue. When
you create a new Handler, it is bound to the thread / message queue of
the thread that is creating it -- from that point on, it will deliver
messages and runnables to that message queue and execute them as they
come out of the message queue.
Now,if you want to update the UI from some other thread that is not the main thread, you will first create a Handler in the main thread and pass it onto any background thread. In the background thread you would do use the post (Runnable r) method to send the message back to the main thread because (read the above paragraph) :) Handlers are not threads, though.
Thread:
A thread is a thread of execution in a program.
Just a generic background processing task.
Looper:
Looper is a class which is used to execute the Messages(Runnables) in
a queue. Normal threads have no such queue, e.g. simple thread does
not have any queue. It executes once and after method execution
finishes, the thread will not run another Message(Runnable).
Sources:
What is the purpose of Looper and how to use it?
What is the difference between a Thread and a Handler
since several days, I tried to figure out what exactly happens if I execute code in
void function(){
//somePreExecutionCode
new Handler().post(new Runnable(){
#Override
public void run(){
//someCode
}
});
}
It seems like it isn't blocking the UI, so buttons, which calls function() doesn't stuck in the clicked position until someCode has finished.
But if somePreExecutionCode starts a progressBar, the progressBar is shown at exactly the same moment, when someCode has finished.
I know, there are AsyncTasks for, but is there any other possibility?
And whats the difference between
new Handler().post
and
View.post
?
When an Android application is created, system creates a main thread of execution. This thread is referred to as UI thread and all UI related operations happen on this thread in order to avoid synchronization issues.
A Looper instance is created on this thread, which has a MessageQueue data structure. The Looper will be in an infinite loop waiting to read the Message / Runnable instances posted on the MessageQueue. To add Message7 / Runnable to the MessageQueue, Handler is used.
When you create a Handler instance, it will be associated with the current thread of execution and the Looper instance created on that particular thread.
Hence when you post a message via a Handler, the Message is added to the MessageQueue, which will be read in FIFO order by Looper and will be delivered to the target.
new Handler().post() and View.post are bit different.
When you post Messages via View.post, you are guaranteed the Message will be posted on UI thread's MessageQueue, since it internally uses Handler instance created on UI Thread.
If you create Handler instance on UI thread and post the Message using it on any thread, Message will be posted to the UI thread's MessageQueue.
If you create Handler instance on a non-UI thread and post Messages using it, they will be posted on non-UI thread's MessageQueue.
Putting it simply, there are Looper threads, for example, UI thread. Such thread has its own Looper, which runs a message loop for the thread.
Such thread, typically, has a Handler, which processes its Looper's messages - overriding public void handleMessage(Message msg) or executing a Runnable, which was posted to it's looper's message queue.
When you're creating a Handler in the context of UI thread (like you did in your code), it gets associated with UI thread's looper, so your \\someCode runs on UI thread.
I guess, in your use case new Handler().post(Runnable) and View:post(Runnable) are mostly the same, as they both add a Runnable to the UI thread message queue.
But they are not the same.
View:post(Runnable) will add a Runnable to the UI thread looper's message queue;
Handler:post(Runnable) will add a Runnable to its associated thread looper's message queue
My explanation is pretty much intuitive, so correct me anyone if I am wrong.
According to the Android View's documentation:
The Runnable will be run on the user interface thread
According to the Android Handler's documentation:
The Runnable will be run on the thread to which this handler is attached
So, in the Handler's case, you can create it in any thread you want, it's a kind of anchor that will execute the Runnable you provide in the thread it was created in.
In the View.post, you will always execute the Runnable in the uI thread.
I have a thread handler which handles the looper of a "worker" thread. At some point in my Activity's lifecycle, I am calling "quit" method on the worker thread which releases its current looper. Then what will happen to the (worker) thread handler?
once you call quit on looper, it will discard all the messages in que and will not take further messages.