Handler mechanism
The application starts from the Main of the ActivityThread and executes looper.prepare (), which creates a new Looper object. The private constructor creates MessageQueue as a member variable of the Looper object, which is bound to the MainThread via ThreadLocal.
When we create a Handler subclass object, we get the bound Looper object through ThreadLocal in the constructor and get the Looper object’s member variable MessageQueue as the Handler object’s member variable.
When the sendMesage(MSG) method of the Handler subclass object created in the previous step is called in the child thread, set the target property of MSG to itself in that method. At the same time, call the enqueueMessag() method of the member variable MessageQueue object to put MSG into MessageQueue;
Once the main thread is created, the looper.loop () method is executed, which retrieves the thread-bound Looper object, which in turn retrieves the member MessageQueue object, and starts an infinite loop that blocks (and consumes no resources). As long as the MessageQueue have MSG, it will get the MSG, and perform the MSG. Target. DispatchMessage (MSG) method (MSG) on the target, namely step reference handler object). This method calls the handleMessage() method that was overridden in our second step when we created the Handler subclass object.
Why doesn’t looper.loop () block the main thread
Stuck is not responding to messages, and that loop is a message processing loop. The main thread of an Android application creates an internal Linux Pipe before entering the message loop. This Pipe enables the main thread of an Android application to enter the idle wait state when the message queue is empty. And causes the application’s main thread to wake up when there is a message to be processed in the application’s message queue
What problems do I need to pay attention to when using Handler and how do I solve them?
The Handler class is not set up as a static class, resulting in a memory leak. The final memory leak occurs in the external class that holds the Handler class
A. Life cycle of the main thread’s Looper object = life cycle of the application
B. In Java, both non-static inner classes and anonymous inner classes hold references to external classes by default. Therefore, Message in the Message queue holds references to Handler instances while there are unprocessed/in-process messages in the Handler Message queue.
Since Handler = non-static inner class/anonymous inner class (both ways), references to the external class (MainActivity instance) are held by default until all messages in the Handler message queue have been processed.
If you destroy the external MainActivity class while there are still unprocessed or processing messages in the Handler message queue, the garbage collector (GC) cannot reclaim the MainActivity due to the above reference, causing a memory leak.
Solution Static inner class + weak reference
Private WeakReference<Activity> reference; Public MyHandler (Activity Activity){reference = new WeakReference<Activity>(Activity); WeakReference<Activity>(Activity); }Copy the code
When the external end of the class life cycle, empty message queue within the Handler mHandler. RemoveCallbacksAndMessage (null);