SoFunction
Updated on 2025-04-08

Android Handler removal Message detailed explanation and example code

Android Handler removal Message details

question:

(what) Does the function only remove the Message corresponding to what value?

2. Can the Message sent by Delayed be removed in advance?

Code Test:

package ; 
 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
import ; 
 
public class TestHandlerActivity extends Activity implements OnClickListener { 
 
  private Button startBtn; 
  private Button endBtn; 
  public Handler threadHandler; //Child thread Handler 
  private Handler mHandler = new Handler() { 
    public void handleMessage( msg) { 
      (1, 2000); 
      ("info", "handle main-thread message..."); 
    }; 
  }; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    (savedInstanceState); 
    setContentView(); 
 
    startBtn = (Button) findViewById(); 
    endBtn = (Button) findViewById(); 
    (this); 
    (this); 
 
    new Thread(new Runnable() { 
      @Override 
      public void run() { 
        HandlerThread handlerThread = new HandlerThread("handler"); 
        (); 
        threadHandler = new Handler(()) { 
          @Override 
          public void handleMessage(Message msg) { 
            //(0, 2000);<span style="font-family: Arial, Helvetica, sans-serif;">         </span> 

<span style="white-space:pre"></span><pre name="code" class="java"><span style="white-space:pre">            </span>(1, 2000); 
("info", "handle sub-thread message...");}};}}).start();}@Overridepublic void onClick(View v) 
{// TODO Auto-generated method stubswitch (()) {case : 
//Start sending messages (1);break;case://Remove the main threadHandlerNews(1);break;default:break;}}}

Test results:

1. removeMassage(1) cannot remove the Message with what=0.

2. Completed execution in the child thread

<span></span><pre name="code" class="java"><span style="white-space:pre"> 
   </span>(1, 2000); 
("info", "handle sub-thread message...");

After that, the message can be removed by removingMesage(1), and the mHandler will not be able to receive the message.

Source code analysis:

How to remove a Message?

Check the source code and you can see that (int what) internal call (this, what, null)

Check the removeMessage method of MessageQueue as follows:

void removeMessages(Handler h, int what, Object object) { 
    if (h == null) { 
      return; 
    } 
 
    synchronized (this) { 
      Message p = mMessages; 
 
      // Remove all messages at front. 
      while (p != null &&  == h &&  == what 
         && (object == null ||  == object)) { 
        Message n = ; 
        mMessages = n; 
        (); 
        p = n; 
      } 
 
      // Remove all messages after front. 
      while (p != null) { 
        Message n = ; 
        if (n != null) { 
          if ( == h &&  == what 
            && (object == null ||  == object)) { 
            Message nn = ; 
            (); 
             = nn; 
            continue; 
          } 
        } 
        p = n; 
      } 
    } 
  } 

The conditions for filtering the Message to be removed are: target (handler), what, object

This function removes the Message in two steps:

1). Remove the Message that meets the criteria in the front end

2). Remove the following Message that meets the criteria

2. Why can delayed sending Messages be removed before the delay time arrives?

() ---Call ---Call ---Call ---Call ---Call ---Call ---Call ---Call ---Call

The actual processing is MessageQueue, the source code is as follows:

boolean enqueueMessage(Message msg, long when) { 
    if (()) { 
      throw new AndroidRuntimeException(msg + " This message is already in use."); 
    } 
    if ( == null) { 
      throw new AndroidRuntimeException("Message must have a target."); 
    } 
 
    synchronized (this) { 
      if (mQuitting) { 
        RuntimeException e = new RuntimeException( 
             + " sending message to a Handler on a dead thread"); 
        ("MessageQueue", (), e); 
        return false; 
      } 
 
       = when; 
      Message p = mMessages; 
      boolean needWake; 
      if (p == null || when == 0 || when < ) { 
        // New head, wake up the event queue if blocked. 
         = p; 
        mMessages = msg; 
        needWake = mBlocked; 
      } else { 
        // Inserted within the middle of the queue. Usually we don't have to wake 
        // up the event queue unless there is a barrier at the head of the queue 
        // and the message is the earliest asynchronous message in the queue. 
        needWake = mBlocked &&  == null && (); 
        Message prev; 
        for (;;) { 
          prev = p; 
          p = ; 
          if (p == null || when < ) { 
            break; 
          } 
          if (needWake && ()) { 
            needWake = false; 
          } 
        } 
         = p; // invariant: p ==  
         = msg; 
      } 
 
      // We can assume mPtr != 0 because mQuitting is false. 
      if (needWake) { 
        nativeWake(mPtr); 
      } 
    } 
    return true; 
  } 

From the above, we can see that MessageQueue will sort the Messages that need to be sent delayed, and will be based on the length of delay (when).

That is, although it is a delayed message, after you call the send function, the Message has been added to the MessageQueue.

Thank you for reading, I hope it can help you. Thank you for your support for this site!