This article’s wechat official account “Android Xiaoyu” was launched

background

Recently, I took over a new project and encountered a Bug related to Handler, which took a lot of time in the process of solving. Finally, I solved it through another idea.

In this article to share with you, but also for you later encountered Handler related problems can quickly locate and solve.

Problem description

The problem is that the message sent by the Handler is not received in the handleMessage.

Of course, the place to send the message and the place to receive the message are not the same file.

You can think of handlers as being managed uniformly through a HashMap.

Idea 1

Is it possible that the Handler sent is different from the Handler received?

After all, it’s managed by HashMap, so could it be replaced?

To verify this, print a reference to the Handler. The result is the same Handler.

Idea 2

Will the sent message be removed?

Verify: by introducing a new unique MSG. What, the result is not received.

Idea 3

/** * Sends a Message containing only the what value. * * @return Returns true if the message was successfully placed in  to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendEmptyMessage(int what)  { return sendEmptyMessageDelayed(what, 0); }Copy the code

Through the comments of the source code, it is found that if the message is already in the queue, it will not be inserted, but if the queue already exists, it should not be missed.

The final print return value is also correct.

So that doesn’t solve the problem, but because of that, it opens up another idea, which is could the queue get blocked, the message get stuck?

Final validation method

So we finally introduce IdleHandler to verify that the message queue is in trouble and that there are no idle message callbacks.

The IdleHandler, just to be very brief, is usually called back when the Handler is idle, and if you listen and don’t remove it, it keeps calling back.

One use is to delay initialization to speed up interface rendering.

For more information, see:

IdleHandler

Finally, it is confirmed that there are no callbacks to use IdleHandler in the sending thread (child thread), whereas the original Handler was built in the main thread.

Therefore, the root cause is that the Handler thread is modified, and the child thread is constantly producing messages, so that the queue may be occupied, so that new messages cannot be received.