Related concepts
1.Handler: Can be viewed as a tool class, used to insert messages into message queues;
2.Thread: All handler-related functions are inextricably linked to thread, and handler are bound to the threads on which they were created;
3.Message: Message;
4.MessageQueue: Message queue, management of the message, implementation of an information link list;
5.Looper: Message loop, take out messages from the MessageQueue for processing;
6.HandlerThread: Inherit thread, create Looper object automatically when instantiating, implement a message loop thread.
Threads are often used in Android development, and when you think of threads, you tend to think of:
New Thread () {...}. Start ();
Such a way. So if the above code is invoked multiple times in an activity, then multiple anonymous threads will be created, and if those threads are not destroyed, that will definitely affect performance. That's when I think about the class Handlerthread that Android provides for an asynchronous processing thread.
The use of general handler
Handler Handler = new Handler () {...};
The handler created in this way is the handler under the main thread, the UI thread, that the handler is bound to the default looper under the UI thread (and, of course, only the main thread can do so, and the child threads cannot do this unless they create a looper themselves). Therefore, sometimes the UI main thread is occupied, causing some problems, so we thought of recreating the child thread to handle the handler ....
using Handlerthread to solve problems
Handlerthread actually inherits from thread, but it's a looper more than normal thread. We can use the following example to create a handler
Handlerthread thread = new Handlerthread ("Myhandlerthread");
Thread.Start ();
When you create a handlerthread, you start it, calling the start () method.
Then there is the use of handler, as follows:
Mhandler = new Handler (Thread.getlooper ());
Todo:you can post or send something ....
The Looper object in Handlerthread is passed in when the handler is created. So this Mhandler object is bound to the Handlerthread thread (this is no longer tied to the UI thread, so it handles time-consuming operations without blocking the UI).
Flowchart of message processing in threads
The location of the message insertion queue is determined by the parameter uptimemillis.
Handler Relationship to Threads
1.HandlerThread is a thread that encapsulates the looper.
The 2.Handler is bound to the thread where the instantiation occurs.
UI thread is associated with child thread communication
1. You need to update the UI, you need to send a message using the handler that is bound to the main thread, or throw an exception if you use the handler created in the child thread;
2. Instantiating the handler object in a child thread requires first calling Looper.prepare (), or it throws an exception;
3. Call the Looper.loop () method message loop before it starts;
Some areas to be noted when using handler
Looper.prepare (), the main thread uses handler, the system defaults to prepare, the child thread creation handler must precede Looper.prepare (), followed by Looper.loop ();
The source code:
Main thread:
The system has automatically invoked the Looper.prepare () method when the program is started. View Main () in Activitythread
public static void Main (string[] args) {
samplingprofilerintegration.start ();
Closeguard.setenabled (false);
Environment.initforcurrentuser ();
Eventlogger.setreporter (New Eventloggingreporter ());
Process.setargv0 ("<pre-initialized>");
Looper.preparemainlooper ();
Activitythread thread = new Activitythread ();
Thread.attach (false);
if (Smainthreadhandler = = null) {
Smainthreadhandler = Thread.gethandler ();
}
Asynctask.init ();
if (false) {
looper.mylooper (). setmessagelogging (New Logprinter (Log.debug, "Activitythread"));
Looper.loop ();
throw new RuntimeException ("Main thread loop unexpectedly exited");
}
Please note looper.preparemainlooper ():
public static final void Preparemainlooper () {
prepare ();
Setmainlooper (Mylooper ());
if (process.supportsprocesses ()) {
mylooper (). mqueue.mquitallowed = false;
}
}
Child Threads:
New Thread (New Runnable () {
@Override public
void Run () {
looper.prepare ()
handler2 = new Handler ();
Looper.loop ()
}
}). Start ();
If there is no Looper.prepare (). Error:
Can ' t create handler inside thread that has not called looper.prepare ()
Because no Looper object was created
Looper.prepare () Source:
public static final void prepare () {
if (sthreadlocal.get ()!= null) {
throw new RuntimeException ("Only one Loop Er may is created per thread ");
}
Sthreadlocal.set (New Looper ());
}