Android: I didn’t even answer the Handler in the interview. Can you answer all these questions?

Insert image description here

When it comes to handlers, what do everyone think of, switching threads? Delay operation? So do you understand the design principles of " IdleHandler, synchronization barrier, infinite loop "? And " IntentService, BlockCanary " derived from the Handler mechanism ?

As a frequent visitor to Android interviews, the probability of Handler being asked is very high, which is just right. Recently, a friend encountered these questions in the interview.

"Interview question 1: Where is the looper of the main thread??"

Take a look at the source code. There is a class involved here android.app.ActivityThread. The main method in this class is the first execution method of the entire app and is the entrance to the app. Take a look at the "main method source code"

Looper.prepareMainLooper();
// ***
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
    
    
    sMainThreadHandler = thread.getHandler();
}
if (false) {
    
    
    Looper.myLooper().setMessageLogging(new
    LogPrinter(Log.DEBUG, "ActivityThread"));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
Looper.prepareMainLooper();
Looper.loop();

The most important of them are these two sentences. The prepareMainLooper method is called to create the Looper of the main thread, and then the loop method is called to start an * infinite loop*

ok, the loop method is found. So why can Looper keep getting messages ? Look at the source code

//Looper
public static void loop() {
    
    
    //...
    for (; ; ) {
    
    
        // 不断从 MessageQueue 获取 消息
        Message msg = queue.next();
        if (msg == null) {
    
    
            // No message indicates that the message queue is quitting.
            return;
        }
        //...
    }
}

Found the reason. In fact, it is an infinite loop , so Looper can always perform the work of the tool man.

"Interview question 2: Why is there an infinite loop? Is this writing method scientific? Doesn't it know oom??"

To put it bluntly, the infinite loop is actually intentional. The thread will terminate after the executable code is executed, and the main thread definitely needs to run all the time, so the infinite loop can guarantee this.

"How to deal with affairs outside of the infinite loop?"

Since the main thread is in an infinite loop, what should be done if there are other transactions? Create a new thread. Before the main thread is created, some other binder threads will be created, such as ApplicationThraed.

"Would an infinite loop waste CPU resources?"

When there is no message, the messageQueue of the main thread will be blocked in the loop queue.nextmethod. At this time, the main thread will release the CPU resources and enter the sleep state until the next message arrives, so it will not consume CPU resources all the time.

"How does the activity life cycle realize normal execution outside the infinite loop?"

In fact, through this **"handler"**, such as the onPause method, when the main thread Looper receives a pause message when it is in the loop, it will distribute the message to the main thread for processing, and then finally call the activity's onPause method handleMessage. . So where does the news from the main thread come from? As mentioned just now, some binder threads will be created in addition to the main thread, such as app threads and system threads. Generally, system threads will ApplicationThreadProxypass messages to the APP thread ApplicationThread, and then pass them to the main thread, which is the thread where ActivityThread is located.

"Interview question 3: Memory leak??"

Why is a memory leak sent in the first place? As an internal class, the handler will hold a reference to the external class. When sending a delayed message, the activity may have been destroyed when the message is processed, resulting in a memory leak.

How to deal with it? Define a static inner class and remove all messages in ondestory

Isn’t it enough to just remove it? Do you still need static inner classes? The onDestory method may not be executed. If your Activity is not at the top of the stack and the app is forcibly killed in the background, onDestory will not be executed.

Above code:

private static class MemoryLeakSafeHandler extends Handler {
    
    

    private WeakReference<HandlerInfoActivity> ref;

    public MemoryLeakSafeHandler(HandlerInfoActivity activity) {
    
    
        this.ref = new WeakReference(activity);
    }

    @Override
    public void handleMessage(final Message msg) {
    
    
        HandlerInfoActivity activity = ref.get();
        if (activity != null) {
    
    
            activity.handleMessage(msg);
        }
    }
}

MemoryLeakSafeHandler handler;

public void handleMessage(Message msg) {
    
    

}

@Override
protected void onDestroy() {
    
    
    handler.removeCallbacksAndMessages(null);
    super.onDestroy();
}
"Interview question 4: What is IdleHandler and what is it used for?"

IdleHandlerIt is a mechanism used to handle idle tasks when the Hanlder is idle, that is, when there are no messages to process. What does it do? Mainly used to improve performance, you can do something when the message queue is idle, so as not to affect the task processing of the main thread. (You humble little brothers, you important brothers use it first, and I use it last).

Usage is as follows:

Looper.myQueue().addIdleHandler(new IdleHandler() {
    
      
    @Override  
    public boolean queueIdle() {
    
      
        //do something
        return false;    
    }  
});

The return parameter of this queueIdlemethod is of bool type. True means that it will not be deleted after executing it once. The callback method will be called the next time it is idle. false means that the IdleHandler will be deleted after executing it once. The source code is in the next method of the MessageQueue class. In fact, when there is no message in the message queue, the queue will be queried. If the mIdleHandlersmIdleHandlers queue has data, it means that if there is an IdleHandler, it will be processed and executed. Let’s simply put down the source code:

Message next() {
    
    
        for (;;) {
    
    
            synchronized (this) {
    
    
                // If first time idle, then get the number of idlers to run.
                // Idle handles only run if the queue is empty or if the first message
                // in the queue (possibly a barrier) is due to be handled in the future.
                if (pendingIdleHandlerCount < 0
                        && (mMessages == null || now < mMessages.when)) {
    
    
                    pendingIdleHandlerCount = mIdleHandlers.size();
                }
                if (pendingIdleHandlerCount <= 0) {
    
    
                    // No idle handlers to run.  Loop and wait some more.
                    mBlocked = true;
                    continue;
                }

                if (mPendingIdleHandlers == null) {
    
    
                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
                }
                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
            }

            // Run the idle handlers.
            // We only ever reach this code block during the first iteration.
            for (int i = 0; i < pendingIdleHandlerCount; i++) {
    
    
                final IdleHandler idler = mPendingIdleHandlers[i];
                mPendingIdleHandlers[i] = null; // release the reference to the handler

                boolean keep = false;
                try {
    
    
                    keep = idler.queueIdle();
                } catch (Throwable t) {
    
    
                    Log.wtf(TAG, "IdleHandler threw exception", t);
                }

                if (!keep) {
    
    
                    synchronized (this) {
    
    
                        mIdleHandlers.remove(idler);
                    }
                }
            }

        }
    }

Some people may want to ask, is this thing really useful? It does work, you just don't use it. Here are two examples of scenarios:

  • For example, if I want to improve the startup speed of the page, I can put some operations in onCreate and onResume into it IdleHandlerto reduce the startup time.
  • LeakcanaryIf the third-party library also uses this class, what is it used for? The UI operation that monitors the main thread is completed. Since all the execution has come to me, it means that the UI operations have been completed, right?
"Interview question 5: What is the synchronization barrier mechanism and what is its use?"

Let’s look at this next method of getting messages:

Message next() {
    
    
        for (; ; ) {
    
    
            synchronized (this) {
    
    
                if (msg != null && msg.target == null) {
    
    
                    // Stalled by a barrier.  Find the next asynchronous message in the queue.
                    do {
    
    
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());
                }
                if (msg != null) {
    
    
                    if (now < msg.when) {
    
    
                        // Next message is not ready.  Set a timeout to wake up when it is ready.
                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                    } else {
    
    
                        // Got a message.
                        mBlocked = false;
                        if (prevMsg != null) {
    
    
                            prevMsg.next = msg.next;
                        } else {
    
    
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        return msg;
                    }
                } 
            }
        }
    }

You can see that there are two conditions for judging this message at the beginning:

  • msg is not empty
  • The target of msg is empty

Then this kind of message is a synchronization barrier message. If you encounter this kind of message, you will enter a dowhile loop to find the asynchronous message in the message queue and return. So this synchronization barrier mechanism is to allow the handler to execute asynchronous messages first, and then execute synchronous messages until the barrier is removed. Wait, why haven’t I heard of asynchronous messages before? Ha ha. Yes, there is. Message has a setAsynchronousmethod. If true is passed in, it means that the message is an asynchronous message and can be executed first after the synchronization barrier occurs. The purpose is to insert some more important messages that need to be processed first.

The specific usage method is:

  • postSyncBarrier method adds barrier
  • removeSyncBarrier removes the barrier but both methods have been marked as hide, and reflection must be used to use them.

Ok, after understanding it, someone should ask again, what is the use? This synchronization barrier. If you have read the source code of view drawing, you will find that ViewRootImplthis is used in the class. Since the priority of view drawing is relatively high, after turning on the synchronization barrier, you can choose to let certain operations be executed first, which increases the priority. For example, the drawing processing operation of this view.

IdleHandlerHey, this mechanism feels like it corresponds to the previous one . One is a humble younger brother? One is the online big brother?

I just chose these interview questions, and after reading them, you have no new understanding of Handler.

Of course, I have been sorting out these latest interview questions and analyzing them during this period. I apologize for any deficiencies in the analysis.

If you need more detailed analysis of interview questions, you can scan the QR code to get it for free! !

Since the interview content is relatively large and the space is limited, the information has been organized into PDF documents. If you need the complete document of the answers to the most comprehensive Android intermediate and advanced interview questions in 2023, you can

Table of contents

img

Chapter 1 Java

●Java basics

●Java collection

●Java multithreading

●Java virtual machine

img

Chapter 2 Android

●Related to the four major components of Android

●Android asynchronous tasks and message mechanism

●Android UI drawing related

●Android performance tuning related

●IPC in Android

●Android system SDK related

●Third-party framework analysis

●Comprehensive technology

●Data structure aspect

●Design pattern

●Computer network aspects

●Kotlin aspect

img

Chapter 3 Audio and video development high-frequency interview questions

●Why can a huge original video be encoded into a small video? What is the technology involved?

●How to optimize live streaming instantly?

●What is the most important role of histogram in image processing?

●What are the methods of digital image filtering?

●What features can be extracted from images?

●What are the criteria for measuring the quality of image reconstruction? How to calculate?

img

Chapter 4 Flutter high-frequency interview questions

●Dart part

●Flutter part

img

Chapter 5 Algorithm High Frequency Interview Questions

●How to find prime numbers efficiently

●How to use binary search algorithm

●How to effectively solve rainwater problems

●How to remove duplicate elements from an ordered array

●How to perform modular exponentiation operation efficiently

●How to find the longest palindromic substring

img

Chapter 6 Andrio Framework

●Analysis of system startup process interview questions

●Binder interview question analysis

●Handler interview question analysis

●Analysis of AMS interview questions

img

Chapter 7 174 common interview questions in companies

●SD card

●Android data storage method

●Broadcast Receiver

●What are the consequences of frequent sp operations? How much data can sp store?

●The difference between dvm and jvm

●ART

●Activity life cycle

●Can Application start Activity?

●…

img

Guess you like

Origin blog.csdn.net/Android_XG/article/details/132293709
Recommended