The interview scene

Do you normally use other threads for development? How are they handled?

You basically use RxJava thread scheduling switches, that’s right, observeOn and subscribeOn that can be handled directly, like network operations, and RxJava provides something called IO threads.

Were there any other ways of doing things before RxJava became widely available? Like Handler or something?

Of course I have.

Why don’t you tell me how Handler works?

Handler workflow includes Handler, Looper, Message and MessageQueue. However, in our daily development, we often only use Handler and Message classes. Message is responsible for carrying messages, which has a target to mark messages, obj to store content, and Handler to distribute and process messages.

How is Handler used in development?

Official UI updates are not allowed in child threads, so we often send UI updates directly to the Handler and override the Handler’s handleMessage() method.

Is there anything you should pay attention to in use?

If Handler is set to private, Android Studio will warn you that it may be leaking memory. This can be done by setting it to static inner class + weak reference. Or in onDestroy () method invocation Handler. RemoveCallbacksAndMessages (null) can be avoided;

The body of the

In general, the interview of the children’s shoes answer is not so bad, but the degree of detail is not enough, so the dust will come to take you into the Handler.

Handler Workflow Analysis

Preparing for asynchronous communication => Message queuing => Message loop => Message processing

  1. Preparation for asynchronous communication assuming that a Handler is created on the main thread, the processor object Looper, MessageQueue object MessageQueue, and Handler object are created directly on the main thread. Note that both Looper and MessageQueue belong to their thread of creation. PrepareMainLooper () and Looper.prepare() are used to create Looper objects. MessageQueue is automatically created when Looper objects are created. Once MessageQueue is created, Looper will automatically enter the message loop. At this point, the Handler automatically binds the main thread’s Looper and MessageQueue.

  2. Message enqueueing The worker thread sends a Message to the Message queue MessageQueue through the Handler. The Message content is usually UI operations. SendMessage (Message MSG) and handler. post(Runnabe r) are used to send messages. And team is usually by MessageQueue. EnqueueeMessage (Message MSG, long the when) to deal with.

  3. The Message loop is divided into two steps: “Message out queue” and “Message distribution”. Looper will loop out the Message in the Message queue MessageQueue and distribute it to the Handler that creates the Message. If the MessageQueue MessageQueue is empty during the message loop, the thread blocks.

  4. Message Processing Handler receives the message from Looper and processes the message.

There are a few caveats to this Handler

  • A threadThreadOnly one circulator can be boundLooper, but there can be multiple processorsHandler
  • 1 circulatorLooperMultiple handlers can be boundHandler
  • One handlerHandlerOnly one circulator can be boundLooper

How are these related objects typically created?

Looper is created from looper.prepare () and looper.prepareMainlooer ().

We have to look at what the Looper constructor does.

Obviously, the MessageQueue object MessageQueue was created automatically when the Looper object was created.

PrepareMainLooper () creates objects directly in the main thread, as the name suggests. The looper.prepare () method is rarely used in our daily development because we often use handlers on the main thread.

Looper and MessageQueue are generated and the message loop is automatically entered: looper.loop ().

Messagequeue.next () is used to fetch the message and set the blocking state.

We use an infinite for loop to fetch messages. When there are no messages, the flag bit nextPollTimeOutMillis is set to -1. During the next loop, nativePollOnce() directly blocks it.

Look at how our messages distributed processing, mainly look at the MSG. Target. DispatchMessage (MSG) method.

MSG. Target returns a Handler object, so let’s see what handler. dipatchMessage(Message MSG) does.

Conclusion:

  • In the main threadLooperObjects are automatically generated without manual generation. In child threads, you must callLooper.prepare()createLooperObject. If it is not created manually in the child thread, it cannot be generatedHandlerObject.
  • Distribute messages toHandlerThe process is: according to the owner of the team message, throughdispatchMessage(msg)Distribute, and finally write backhandleMessage(Message msg).
  • In message distributiondispatchMessage(msg)Method is used to determine the sending mode: 1msg.callbackProperty is null, indicating that it is usedpost(Runnable r)If a message is sent, the callback is made directlyRunnableOverwrite the object insiderun(). If 2.msg.callbackProperty is not empty, indicating usesendMessage(Message msg)Send message, direct callback overwrittenhandleMessage(msg).

How is a regular Message Message created?

We often create the Message object Message in the use of a Handler, either by two new Messages () or message.obtain (). Message.obtain() is generally preferred because it avoids the repeated creation of Message objects. It’s actually obvious in the code.

Another way to use Handler

Handler.sendMessage(Message MSG) is used in general. In fact, we sometimes use handler. post(Runnable r).

As you can see from the official comment, this adds the Runnable object directly to the message queue, so let’s see what ‘getPostMessage(r)’ actually does.

Our analysis above is correct. In the getPostMessage(Runnable R) method, in addition to creating the Message object through the message.obtain () method, we assign the Runnable object to the callback so that when we distribute the Message above, This flag is used to determine whether post() or sendMessage() is used.

How exactly do you send messages?

I’ve been talking about sending messages via sendMessage(), but how exactly is this message sent?

Just look at sendMessageAtTime().

What does enqueueMessage() do?

At this point, you can see the difference between the two approaches.

Write in the last

This content may speak more and chaos, but also hope that we follow the source code step by step analysis, the most difficult time, is to promote the largest time!

I am the south dust, only do than the heart of the public number, welcome to pay attention to me.