Do you understand Handler’s basic, intermediate, and advanced questions?

Create a Looper for the thread

class LooperThread extends Thread {

    public Handler mHandler;
    
    public void run(a) {
        Looper.prepare();
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here}}; Looper.loop(); }}Copy the code

Cause of memory leak

Android: Little things about Handler memory leaks

  1. Non-static inner class
class MyHandler extends Handler {
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg); }}Copy the code
  1. Anonymous inner class
Handler handler = new Handler() {
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg); }};Copy the code

In Java, non-static inner classes & anonymous inner classes both hold references to external classes by default.

In Handler Message queues, while there are still unprocessed messages/in-process messages, the Message in the Message queue holds references to Handler instances, which in turn hold references to external classes. If an external class is destroyed at this point, the garbage collector (GC) will not be able to reclaim MainActivity due to the above references, resulting in a memory leak.

Solution 1: Static inner class + weak reference

static class MyHandler extends Handler {

    private WeakReference<Activity> reference;
    
    public MyHandler(Activity activity) {
        reference = new WeakReference<>(activity);
    }
    
    @Override
    public void handleMessage(@NonNull Message msg) {
        super.handleMessage(msg); }}Copy the code

Solution 2: Empty the message queue inside the Handler when the external class ends its life cycle

@Override
protected void onDestroy(a) {
    super.onDestroy();
    mHandler.removeCallbacksAndMessages(null);
}
Copy the code

Why does looper loop death not cause apps to freeze

  1. A thread is a piece of executable code. When the executable code completes, the thread life cycle terminates and the thread exits. For the main thread, we do not want to be run for a period of time, and then exit, so how to ensure that it is always alive? The simple idea is that executable code can be executed forever, and an infinite loop is guaranteed to never exit.

  2. Really getting stuck the operation of the main thread is in the callback method onCreate/onStart/onResume operating time is too long, can lead to a frame, even ANR, stars. The loop () itself does not result in application.

  3. How can you do anything else if it’s an infinite loop? By creating a new thread.

  4. Is the main thread running in an endless loop particularly CPU intensive?

The nativePollOnce() method in the loop’s queue.next() is blocked when the main thread MessageQueue has no message. The main thread then releases CPU resources and goes to sleep until the next message arrives or a transaction occurs, waking up the main thread by writing data to the pipe end. The main thread is dormant most of the time and does not consume significant CPU resources.