The original link

This article shares the use and reuse of Messages in the Handler messaging mechanism.

Other articles in the series

  1. Handler Message mechanism (1) Message reuse principle
  2. Handler message mechanism (2) ThreadLocal principle
  3. Handler Message mechanism (3) MessageQueue principle
  4. Handler Message mechanism (4) Looper principle
  5. Handler Message mechanism (5) Handler principle

Contains the following two parts:

  • How Message is used in the Handler
  • Message reuse principle

In Android development, the use of Handler to achieve communication between threads, very convenient, when frequent message communication, every time to new message object, in the creation of the object of the system resource occupation, at the same time GC frequent object recycling, memory and system performance will have a certain impact. When message events are frequently handled by handlers, obtainMessage() is recommended to obtainMessage instances. This method obtains messages from object pools, using the design idea of the share mode.

After only understanding how Message is used, we should also know what it is. On how to achieve Message reuse, I will analyze the reuse idea from the source level later.

1. How to use Message in Handler

The use of Message in Handler is very simple. Use it in either of the following ways: Method 1: New Message object

Message msg = new Message(); // new new object msg.what = 100; msg.obj = obj; mHandler.sendMessage(msg);Copy the code

Method 2: Reuse message objects in the pool

  Message msg = mHandler.obtainMessage();
  msg.what = 100;
  msg.obj = obj;
  mHandler.sendMessage(msg);
Copy the code

or

  Message msg = Message.obtain(mHandler);
  msg.what = 100;
  msg.obj = obj;
  mHandler.sendMessage(msg);
Copy the code

2. Principle of Message reuse

First of all, according to the definition of Message data structure, it can be seen that Message adopts one-way linked list structure to achieve the management of Message objects, and records table header data through sPool. In order to understand the principle of reuse, the following key parameters of Message, Message pseudocode structure, were extracted:

Int sPoolSize, // Number of messages in the pool Message sPool, // Current Message, i.e. Message next, // Next node of current Message int what... // Other parametersCopy the code

2.1 Reclaim message objects

The newly collected message is placed in the table header, and the message in the current table header is recorded by sPool. The next node of sPool is the message recorded by sPool before recycling

Source code Message recycle Message recycleUnchecked:

void recycleUnchecked() { // Mark the message as in use while it remains in the recycled object pool. // Clear out all other details. flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; }}}Copy the code

Abstract pseudocode:

next= sPool; // Next may be null sPool = this; sPoolSize++;Copy the code

Assume the order of Message collection: MSG1 -> MSG2 -> MSG3

Step 1, when message MSg1 is recycled:
msg1.next = sPool; // sPool is null sPool = msg1;Copy the code
Step 2, when message MSg2 is recycled:
msg2.next = sPool; // sPool is msg1 sPool = msg2;Copy the code
Step 3, when message MSG3 is recycled:
msg3.next = sPool; // sPool is msg2 sPool = msg3;Copy the code

The recycled linked list structure is:

  sPool = msg3,msg3.next -> msg2,msg2.next -> msg1,msg1.next -> null
Copy the code

2.2 Obtaining Object Pool Messages

  • If sPool is null, create a new Message
  • If sPool is not null, the Message object is fetched from the object pool and is queried each time from the table header, which is the table header Message that sPool records.

Get message from Handler:

  public final Message obtainMessage() {
      return Message.obtain(this);
  }
Copy the code

Get Message from Message:

public static Message obtain() { synchronized (sPoolSync) { if (sPool ! = null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }Copy the code

Abstract pseudocode:

if(null ! = sPool) { Message m = sPool; sPool = m.next sPoolSzie--; return m; } return new Message();Copy the code

Suppose the message list structure is (the header is MSG3) :

  sPool = msg3,msg3.next -> msg2,msg2.next -> msg1,msg1.next -> null
Copy the code
Step 1, get the message MSG3:
Message m = sPool; // sPool is msg3 sPool = m.next; Next is msg2, sPool is pointing to msg2 return m; M is the header msg1Copy the code
Step 2, get message MSg2:
Message m = sPool; // sPool is msg2 sPool = m.next; Next is msg1 return m; // m is the header msg2Copy the code
Step 3, get message MSg1:
Message m = sPool; // sPool is msg1 sPool = m.next; // m.next = msg1.next = null return m; M is the header msg1Copy the code
Step 4, when there is no message in the object pool:
  return new Message();
Copy the code

Through the analysis of the principle of Message object reuse, in fact, the Message recycling and acquisition during the reuse of objects adopts the idea of stack, that is, first in, last out (FILO) principle, that is, the latest recycled objects will be used again first. This article will help you to use Message properly in the development process.

Conclusion: In the case of infrequent use of message objects in development, just new; If you need to use message objects frequently, you can reuse them to reduce the consumption of new objects and process message events more efficiently.

The original link