Tag Archives: Can’t create handler inside thread that has not called Looper.prepare()

Can’t create handler inside thread that has not called Looper.prepare()

Open source software supply chain lighting plan, waiting for you>>>

Question: can’t create handler inside thread that has not called looper. Prepare ()

1. Add looper. Prepare () before the error reporting method
loop. Loop() is added at the end of the method

2. The cause of the problem:
in the multi-threaded development of Android, such as asynctask, the doinbackground() method calls the UI update method

Solution:
put the operation of updating UI into message processor for processing; Send update message in doinbackground() method:

Handler updateDate = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case LOADING_ FINISHED:
listView.setAdapter(gameAdapter);
break;
}
}
};

3,
toast and looper. Handler message loop mechanism

(1) The looper class is used to open a message loop for a thread. By default, the new thread in Android does not open the message loop( Except for the main thread, the system of the main thread will automatically create a looper object for it and open a message loop.)

The looper object stores messages and events through the message queue. A thread can only have one looper, corresponding to one message queue

(2) It is usually through the handler object to interact with the looper. Handler can be regarded as an interface of looper, which is used to send messages to the specified looper and define processing methods

By default, the handler is bound to the looper of the thread in which it is defined. For example, if it is defined in the main thread, it is bound to the looper of the main thread

Mainhandler = new handler () is equivalent to new handler (looper. Mylooper ())

Looper. Mylooper(): return the looper object associated with the current thread

A similar looper. Getmainlooper() is used to get the looper object of the main thread

(3) In a non main thread, new handler() will report the following error:

E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare()

The reason is that the looper object is not created by default in the non main thread. You need to call looper. Prepare() to enable looper first

(4) Looper.loop(); Let the looper work, get the message from the message queue, and process the message

Note: the code written after loop. Loop() will not be executed. There should be a loop inside this function. When mhandler. Getloop(). Quit() is called, the loop will stop and the subsequent code will run

(5) Based on the above knowledge, the main thread can send messages to the sub thread (non main thread)

There is a handler member variable in toast or dialog, which will be initialized during initialization. However, the handler in toast or dialog needs a looper, so it is necessary to initialize the looper in the thread containing the toast or dialog (such as the timer thread below). Looper.prepare();

Problem code:

Java code
privatehandlermyhandler = newhandler() {
public void handle message (message MSG) {
timer = newtimer()
timer.schedule(newTimerTask(){
@Override
publicvoidrun(){
InputMethodManagerm=(InputMethodManager)editText
.getContext().getSystemService(
Context.INPUT_ METHOD_ SERVICE);
m.showSoftInput(editText,0);
//
Looper.prepare();
Toast.makeText(Main.this,”show”,Toast.LENGTH_ LONG).show();
Looper.loop();
}
},1000);
}
}

Toast and looper, one belongs to android.widget and the other belongs to android.os, two seemingly not closely related classes, are connected by the following exception:

Java code
e/Android runtime (1819): java.lang.runtimee xception:Can ‘tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()
E/AndroidRuntime(1819):atandroid.os.Handler.(Handler. java:121 )
E/AndroidRuntime(1819):atandroid.widget.Toast.(Toast. java:68 )
E/AndroidRuntime(1819):atandroid.widget.Toast.makeText(Toast. java:231 )

Handler.java:121

Java code
mlooper = looper. Mylooper()
if(mLooper==null){
thrownewRuntimeException(
“Can’tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()”);}

Toast.java:68 ——> Member variables are initialized at the same time

Java code
finalhandlermhandler = newhandler()

Java code
classlooperthreadextends thread {
public handler mhandler

publicvoidrun(){
Looper.prepare();
mHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
//processincomingmessageshere
}
};
Looper.loop();
}
}
let’s get to the point and continue to find the connection among toast, looper and handler. Maybe the answer can be solved. To uncover the mystery, starting from the source code is a shortcut

The code in line 231 of toast. Java is to create a new toast instance. In the process of instantiation, you need to execute line 68, that is, declare and create an instance of handler (member variable). Let’s see what line 121 of handler.java does, as follows:

Java code
mlooper = looper. Mylooper()
if(mLooper==null){
thrownewRuntimeException(
“Can’tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()”);}
at this point, it is a big step closer to solving the truth. Since runtimeException is thrown, mlooper must be null, but why does looper. Mylooper() return null?Continue to explore in looper. Java

Java code

public static final loopermylooper() {
return (looper) sthreadlocal. Get()
}
the above is the real face of the mylooper () method. From the comments, we can see that the real reason for the problem is that the current thread is not bound to the looper, and returning null is a correct but abnormal result

original text: https://blog.csdn.net/SamLee1989/article/details/8289631 Thank you