Does handler belong to thread in which it was created? - android

I'm relatively new to the "Looper-Handler" term. I'm pretty clear with the way they work but still confused with their architecture.
I've also gone through couple of SO questions, but still I have some questions regarding them.
To get them clear and to summarize, can anyone answer for the below questions?
Is it true that the Handler belong to the thread in which it was created ?
I'm aware that there can be multiple instances of handler per Looper/MeesageQueue pair. Is it possible create a handler for a thread from some other Thread?
Suppose, in the main thread we write Handler handler = new Handler (x.getLooper()) where x is the handler of another thread X, then to which MessageQueue handler will actually post?
If I'm getting wrong anywhere, please make me correct. Thanks.

Right, if you use default constructor val h = Handler(). Default constructor associates this handler with the Looper for the current thread. If this thread does not have a looper, this handler won't be able to receive messages so an exception is thrown.
Yes. If you use constructor, which accepts Looper val h = Handler(looper), where looper associated with another Thread.
handler will be associated with Thread X, because looper of that thread is used to created the handler.
The 3rd question is similar to the 2nd one.

Related

What's the function of looper for constructor of Handler? [duplicate]

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

difference between Thread and Handler

Can somebody tell me the deference between Thread and Handler? When we use Thread and when we use Handler?
I have two code in my project , But I can't understand them.
final Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
// Do SomeThings
}
};
And
private class readThread extends Thread
{
Handler mHandler;
readThread(Handler h){
mHandler = h;
this.setPriority(Thread.MIN_PRIORITY);
}
#Override
public void run()
{
// Do SomeThings
}
}
And in another method call the handler like this
read_thread = new readThread(handler);
read_thread.start();
Which one run first?? Can somebody explain me?
The same: you can both execute task asynchronously without blocking your current code,
The difference: Imagine you have a Runnable r = new Runnable{...}
When you use new Thread(r).start(), you actually created a new thread and run task asynchronously.
When you use new Handler().post(r) (or Message), you added the Runnable object to Looper and execute the code later in the same thread.
A Thread, generally MainThread or UIThread contains a Looper. When MainThread runs, it will loop the Looper and execute Runnable one by one.
When Thread is preferred:
When you're doing a heavy work like network communication, or decoding large bitmap files, a new thread is preferred. If a lot of thread is needed, maybe ExecutorService is preferred further.
https://developer.android.com/reference/java/util/concurrent/ExecutorService.html
When Handler is preferred:
When you want to update UI objects (like TextView text) from other thread, it is necessary that UI objects could only be updated in UI Thread.
Also, when you just want to run some light code later (like the delay for 300ms) you can use Handler because it's lighter and faster.
Please also refer to Handler vs AsyncTask vs Thread
Thread actually creates new thread - part of job running in background relatively to current thread.
Handler itself doesn't provide any mechanisms for background job - it is just a tool to access message queue (Looper) associated with some thread. UI thread have Looper attached by default, so it is common practice to update UI with Handler.post(Runable) which means execute some piece of code on thread which is associated with this Handler.
As soon as Handler serves Looper, it can't be created in a thread which have no associated Looper.
Threads are generic processing tasks that can do most things, but one thing they cannot do is update the UI.
Handlers on the other hand are background threads that allow you to communicate with the UI thread (update the UI).
So for example show a toast or a update a progress bar via a message (Runnable) posted to a handler but you can't if you start this runnable as a thread.
With handler you can also have things like MessageQueuing, scheduling and repeating.
I am yet to encounter a situation where I needed a thread in android.
I mostly use a combination of AsyncTasks and Handlers.
Handlers for the aforementioned tasks.
AsyncTasks for download/ data fetching and polling etc.
Simply says,
Both are same concepts, but some key differences.
Thread is a java(java.lang) concept and Handler is a android(android.os)OS concept.if you are using Handler instead of Thread , your OS will automatically manage the working of background processes. But if you are using Thread,it is not dependent on your android OS. So Threads can't manage memory efficiently as compared to Handler.
Threads:
You can use the new Thread for long-running background tasks without impacting UI Thread. From java Thread. But here you can't update the UI from Thread.
Since normal Thread is not much useful for Android architecture, helper classes for threading have been introduced.
You can find answers to your queries on the Threading performance documentation page.
Handler:
This class is responsible for enqueuing any task to the message queue and processing them. Each Handler can be associated with one single thread and that thread’s message queue.
There are two main uses for a Handler:
To schedule messages and runnables to be executed as some point in
the future;
To enqueue an action to be performed on a different
thread than your own.
Looper: Looper is a worker that keep a thread alive, It loops over message queue and send the message to respective Handler.
Message Queue: This class holds the list of messages to be dispatched by the looper. You can just call Looper.myqueue() to get list of messages. We do not normally deal with it.

Is a Handler a Thread or not, and what is the role of a Looper with Handlers and Threads?

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

What is the relationship between Looper, Handler and MessageQueue in Android?

I have checked the official Android documentation/guide for Looper, Handler and MessageQueue . But I couldn't get it. I am new to android, and got very confused with these concepts.
A Looper is a message handling loop: it reads and processes items from a MessageQueue. The Looper class is usually used in conjunction with a HandlerThread (a subclass of Thread).
A Handler is a utility class that facilitates interacting with a Looper—mainly by posting messages and Runnable objects to the thread's MessageQueue. When a Handler is created, it is bound to a specific Looper (and associated thread and message queue).
In typical usage, you create and start a HandlerThread, then create a Handler object (or objects) by which other threads can interact with the HandlerThread instance. The Handler must be created while running on the HandlerThread, although once created there is no restriction on what threads can use the Handler's scheduling methods (post(Runnable), etc.)
The main thread (a.k.a. UI thread) in an Android application is set up as a handler thread before your application instance is created.
Aside from the class docs, there's a nice discussion of all of this here.
P.S. All the classes mentioned above are in the package android.os.
It's widely known that it's illegal to update UI components directly from threads other than main thread in android. This android document (Handling Expensive Operations in the UI Thread) suggests the steps to follow if we need to start a separate thread to do some expensive work and update UI after it's done. The idea is to create a Handler object associated with main thread, and post a Runnable to it at appropriate time. This Runnable will be invoked on the main thread. This mechanism is implemented with Looper and Handler classes.
The Looper class maintains a MessageQueue, which contains a list messages. An important character of Looper is that it's associated with the thread within which the Looper is created. This association is kept forever and can't be broken nor changed. Also note that a thread can't be associated with more than one Looper. In order to guarantee this association, Looper is stored in thread-local storage, and it can't be created via its constructor directly. The only way to create it is to call prepare static method on Looper. prepare method first examines ThreadLocal of current thread to make sure that there isn't already a Looper associated with the thread. After the examination, a new Looper is created and saved in ThreadLocal. Having prepared the Looper, we can call loop method on it to check for new messages and have Handler to deal with them.
As the name indicates, the Handler class is mainly responsible for handling (adding, removing, dispatching) messages of current thread's MessageQueue. A Handler instance is also bound to a thread. The binding between Handler and Thread is achieved via Looper and MessageQueue. A Handler is always bound to a Looper, and subsequently bound to the thread associated with the Looper. Unlike Looper, multiple Handler instances can be bound to the same thread. Whenever we call post or any methods alike on the Handler, a new message is added to the associated MessageQueue. The target field of the message is set to current Handler instance. When the Looper received this message, it invokes dispatchMessage on message's target field, so that the message routes back to to the Handler instance to be handled, but on the correct thread.
The relationships between Looper, Handler and MessageQueue is shown below:
Let's start with the Looper. You can understand the relationship between Looper, Handler and MessageQueue more easily when you understand what Looper is. Also you can better understand what Looper is in the context of GUI framework. Looper is made to do 2 things.
1) Looper transforms a normal thread, which terminates when its run() method returns, into something that runs continuously until Android app is running, which is needed in GUI framework (Technically, it still terminates when run() method returns. But let me clarify what I mean, below).
2) Looper provides a queue where jobs to be done are enqueued, which is also needed in GUI framework.
As you may know, when an application is launched, the system creates a thread of execution for the application, called “main”, and Android applications normally run entirely on a single thread by default the “main thread”. But main thread is not some secret, special thread. It's just a normal thread that you can also create with new Thread() code, which means it terminates when its run() method returns! Think of below example.
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Now, let's apply this simple principle to Android app. What would happen if an Android app is run on a normal thread? A thread called "main" or "UI" or whatever starts application, and draws all UI. So, the first screen is displayed to users. So what now? The main thread terminates? No, it shouldn’t. It should wait until users do something, right? But how can we achieve this behavior? Well, we can try with Object.wait() or Thread.sleep(). For example, main thread finishes its initial job to display first screen, and sleeps. It awakes, which means interrupted, when a new job to do is fetched. So far so good, but at this moment we need a queue-like data structure to hold multiple jobs. Think about a case when a user touches screen serially, and a task takes longer time to finish. So, we need to have a data structure to hold jobs to be done in first-in-first-out manner. Also, you may imagine, implementing ever-running-and-process-job-when-arrived thread using interrupt is not easy, and leads to complex and often unmaintainable code. We'd rather create a new mechanism for such purpose, and that is what Looper is all about. The official document of Looper class says, "Threads by default do not have a message loop associated with them", and Looper is a class "used to run a message loop for a thread". Now you can understand what it means.
Let's move to Handler and MessageQueue. First, MessageQueue is the queue that I mentioned above. It resides inside a Looper, and that's it. You can check it with Looper class's source code. Looper class has a member variable of MessageQueue.
Then, what is Handler? If there is a queue, then there should be a method that should enable us to enqueue a new task to the queue, right? That is what Handler does. We can enqueue a new task into a queue(MessageQueue) using various post(Runnable r) methods. That's it. This is all about Looper, Handler, and MessageQueue.
My last word is, so basically Looper is a class that is made to address a problem that occurs in GUI framework. But this kind of needs also can happen in other situations as well. Actually it is a pretty famous pattern for multi threads application, and you can learn more about it in "Concurrent Programming in Java" by Doug Lea(Especially, chapter 4.1.4 "Worker Threads" would be helpful). Also, you can imagine this kind of mechanism is not unique in Android framework, but all GUI frameworks may need somewhat similar to this. You can find almost same mechanism in Java Swing framework.
MessageQueue: It is a low-level class holding the list of messages to be dispatched by a Looper. Messages are not added directly to a MessageQueue, but rather through Handler objects associated with the Looper.[3]
Looper: It loops over a MessageQueue which contains the messages to be dispatched. The actual task of managing the queue is done by the Handler which is responsible for handling (adding, removing, dispatching) messages in the message queue.[2]
Handler: It 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.[4]
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.
Kindly, go through the below image[2] for better understanding.
Extending the answer, by #K_Anas, with an example,
As it stated
It's widely known that it's illegal to update UI components directly from threads other than main thread in android.
for instance if you try to update the UI using Thread.
int count = 0;
new Thread(new Runnable(){
#Override
public void run() {
try {
while(true) {
sleep(1000);
count++;
textView.setText(String.valueOf(count));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
).start();
your app will crash with exception.
android.view.ViewRoot$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
in other words you need to use Handler which keeps reference to the MainLooper i.e. Main Thread or UI Thread and pass task as Runnable.
Handler handler = new Handler(getApplicationContext().getMainLooper);
int count = 0;
new Thread(new Runnable(){
#Override
public void run() {
try {
while(true) {
sleep(1000);
count++;
handler.post(new Runnable() {
#Override
public void run() {
textView.setText(String.valueOf(count));
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
).start() ;

Create Handler in a class without get error "Looper not prepared"?

In my game, there is an game object class that need to use Handler to post a delay Runnable. However, everything I try to create an Handler in the object class, I receive error message:
Can't create handler inside thread
that has not called Looper.prepare()
I've Googled some solution, but all of them use another solution, not Handler. Is there any solution to use Handler in a normal class? Or any solution to run a Runnable after a determined delay?
I can't use sleep, because it paused all my game!
Thank you.
You are probably creating the Handler from a non-UI thread. Either (1) you attach your handler explicitly to the UI thread by passing the UI thread's looper to Handlers constructor, which means that messages posted to the Handler are also executed on the UI thread, or (2) you create a new Looper for the non-UI-thread: see here.
edit regarding (1): you would have to somehow pass the UI thread's looper to the "game object", for example when it is created. You can get a reference to UI's looper by calling getMainLooper() on a context (e.g. from an activity).
An alternative would be to create the handler in the activity and just pass the handler to your game object.

Categories

Resources