Cannot create handler in main thread? - android

A user is getting an error on their phone when executing the code below, I am checking to see if the user is currently on a call or not before I run an AsyncTask making a Web Service call. The reason I am doing this is because some people are losing internet connection when on a call so i check every 5 seconds to see if they are on a call or not. If they are not then AsyncTask gets called
do{
Handler handler = new Handler();
handler.postDelayed(new Runnable(){
#Override
public void run() {
onCall = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
.getCallState() != TelephonyManager.CALL_STATE_IDLE;
if(!onCall){
new CallRegWS().execute();
}
}
},5000);
}while(onCall);
I do not have the full stack trace only this showing me the error
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
obviously not too helpful but that is all I have to go on. they keep getting that error so it must be happening when I create the handler.
All this is done in the main thread so I dont know what the problem is, any insight on how I could fix this?
Update
this is called from a service and the method is in a separate class

Try Handler handler = new Handler(Looper.getMainLooper());
Also, see this post regarding this error: http://levinotik.com/loopers-handlers-runtimeexceptions-explained/

First of all you have to know that, Handlers automatically attach to the thread where are created as specified in the documentation:
Handler Class Overview
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. Handler | Android Developers
Now, taking that on count and since the current thread don't have a message queue, in order to work properly the thread needs an actual "Queue", and that's exactly what the system is telling you to do, by calling Looper.prepare() you are creating a Message Looper within the thread you created because by default Threads do not have a Message looper as mentioned in documentation:
Looper Class Overview
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped. Looper | Android Developers
In other words and in a simple manner, the Main UI DOES have a Message Queue already prepared, and that's why you don't see that error when calling new Handler() within "onCreate, onStart, onResume etc...", but for any worker thread created the system needs a queue to send the messages to when using handlers, although the code doesn't show it, i bet that code is being executed in a worker thread either normal Thread or doInBackground method of an AsyncTask and that's what causes the error, to avoid it remember to always call Looper.prepare before creating a handler from a worker thread.
Hope this Helps.
Regards!

How do you know this is running on the Main thread? And when and where is this getting called from? Instead of creating your handler right before you use it, create it in the onCreate method of your Activity or your Service (depending on what this is).Then in your onDestroy null the value out.

Related

Handler created in main thread acts like it is on another thread

As google says:
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.
And i expect when i create a Handler in main thread (UI thread) it attached to this thread so it cause to freeze ui till end it's task. But in test this not happen and it is acts like it is on a backgound thread and do his task parallel.
I used to create Handle like this:
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i < 35000; i++) {
log.i(TAG,"log in Handler:"+i);
}}
};
mainHandler.post(runnable);
log.i(TAG,"log outSide");
In mainActivity (so handle should bound to Main thread). So what is the problem with this or am i create the handler in wrong way?
Some friends notice that doSomthing() is not complicated enough but why we see "log outSide" before "log in Handler:" if they are in a same thread.
Actually, It's working as you expected, Your handler is currently associated with your main thread because it is created in it and your task is also running on the same. Try to add Thread.sleep(1000) method inside your for loop then you will see the freeze in your UI.
Your current code runs with a complexity of O(1) since your N is constant, and your phone is capable enough to run this in a fraction of a second that's why you are not observing any freeze in your UI during the test.
Some friends notice that doSomthing() is not complicated enough but why we see "log outSide" before "log in Handler:" if they are in a same thread.
This is because of the delay in posting the Runnable to the Handler. Even though the Handler is created with the main thread's looper, there is still a small amount of delay between when post is called and when that Handler message is put into the Handler's queue and executed on the thread.
"log outside" runs instantaneously, so you see that log before the log within the Handler.

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

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

Androids Handler.post, what happens exactly

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.

Android: is it possible to restart Thread's Looper?

I have a simple question: is it possible to restart (re- loop()) thread's Looper if it was previously quit. For instance, i have design my thread as follow:
public class ProvaThread extends Thread implements Runnable{
public void run(){
Looper.prepare();
Handler handler = new Handler(){
Log.d(TAG, "handle message..");
#Override
public void handleMessage(Message msg){
getLooper().quit();
}
};
Looper.loop(); //loop 1
Log.d(TAG, "thread continue (1)...");
Looper.loop(); //loop 2
Log.d(TAG, "thread continue (2)...");
}
}
I have tried this code but i get a RuntimeException (sending message to a Handler on a dead thread) when i try to post a message to the handler the second time (handleMessage() is not called after second loop()). I came to conclusion that when getLooper().quit() is called is it possible to recall loop() but is it not possible to handle new messages, otherwise exception is thrown). Is it correct?
Should i use wait()/notify() to make this??
Let me first explain why your example code doesn't work. A Looper only handles one, and only one, MessageQueue. This MessageQueue is created when you call Looper.prepare() and the messages are processed when you call Looper.loop(). Once you have called Looper.quit() two things happen:
The MessageQueue to the Looper is put in a final terminal state where it will not process any incoming messages; a RuntimeException is thrown.
It will only return "null" as message when the Looper tries to retrieve messages.
So, (1) is the reason for your RuntimeException and (2) allows you to try and and restart the message retrieval with Looper.loop() but only "null"-objects are returned from the MessageQueue.
Secondly, let me suggest a better approach to solve a continuous communication between the UI and a worker thread:
Create a Handler for the UI thread, called mUiHandler.
Create a worker thread, e.g. HandlerThread, and expose a Handler, called mWorkerHandler.
Now, let the two handlers communicate by sending messages back and forth. Post messages to the mWorkerHandler for background tasks and let the worker thread post messages to the mUiHandler whenever a dialog shall be shown or removed.
I think you should read this short article http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/. It explains how Looper works and how to use it.

Categories

Resources