idleHandler

I’ve been doing some performance optimization work recently, and it’s interesting to find that idleHandler is such a magic tool

What is a idleHandler

Android is a system based on Looper Message loop. We use Handler to send messages to MessageQueue contained by Looper. In MessageQueue, we can see such an interface

 /** * Callback interface for discovering when a thread is going to block * waiting for more messages. */
    public static interface IdleHandler {
        /** * Called when the message queue has run out of messages and will now * wait for more. Return true to keep your idle handler active, false * to have it removed. This may be called if there are still messages * pending in the queue, but they are all scheduled to be dispatched * after the current time. */
        boolean queueIdle(a);
    }
Copy the code

In Looper, Messsage is temporarily finished. At this time, the interface will be called back, that is, idle.

The return value

If false is returned, the interface is removed, as if used once, and the message is removed from the queue. If true is returned, the interface is kept until the next Looper is idle. For example, on the main thread return true, there is always polling

role

As you can see from the above, this callback is only called when the message queue is temporarily finished processing, so there are two scenarios that can be used

The UI thread is the main thread

usage

Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle(a) {
                /*dosometing*/
                return false; }});Copy the code

When the UI drawing is complete in Actvity

OnStart is user visible, onResume is user interactive, at this point the drawing is not necessarily done, and idler waits until it’s done to execute itself, so we get some width and height that we can do here.

Improve performance

When doing performance optimization, you can stagger the execution of message queues and put some time-consuming operations here, such as our international driver side, a Google map on the home page, and some text scrolling and ripple animation. At this time, you can put the animation in idleHanlder and let the base image render first.

Custom Looper such as HandlerThread

In addition to the main thread, we can also define our own Looper to handle. In this case, we can have our Looper associated with the idlerHandler to handle other things after the Looper message has been processed.

 MessageQueue messageQueue = handlerThread.getLooper().getQueue();
        messageQueue.addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle(a) {
             
                return true; }});Copy the code

For example, in a single-threaded asynchronous scenario, fast data can be displayed multiple times, but only once

Pay attention to the point

If there is a strong timing of the operation better not to deal with here, prone to problems

reference