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