前言
消息既然有发送,也可以去做取消
移除消息的方法,共计5个,今天一起学习一下它们是怎么实现的?
removeMessages()方法分析
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
用于移除一组Message,Message持有的int值what只要匹配,都会被移除掉。传入参数为int值,表示Message对象持有的一个int值
1、传入的局部变量what持有的int值最终会传入到Handler对象持有的MessageQueue对象mQueue的removeMessages()方法中
2、removeMessages接受三个参数,第一个参数是当前的Handler对象,第二个参数是当前传入的整型what值,最后一个参数这里传入的是null,该参数接受的类型是Object。
3、MessageQueue会将消息队列中,所有what值匹配的未分发出去的Message对象全部移除掉
removeMessages()方法分析(重载方法:2个参数)
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
用于删除多个消息的方法,必须同时匹配what值与object值的消息才会被移除。传入的第一个参数为int,表示Message对象持有的int值,传入的第二个参数为Object,表示Message对象持有的Object对象
1、同样调用Handler对象持有的MessageQueue对象的removeMessages()方法,传入的第一个参数为当前Handler对象,第二个参数为表示用于匹配的int值,第三个参数为Object对象
2、MessageQueue对象的removeMessages()方法,会判断只有what值与object值同时与消息队列中的消息所匹配,才会被全部移除掉
removeCallbacks()方法分析
public final void removeCallbacks(Runnable r)
{
mQueue.removeMessages(this, r, null);
}
用于移除多个消息,只有Message对象持有同样的Runnable对象,才会被移除调用,传入的参数为一个Runnable对象,表示用于匹配的条件
1、调用Handler对象持有的MessageQueue的removeMessages()重载方法,将当前Handler对象、传入的Runnable对象、以及一个null值均传了进去
2、此处会对消息队列中的所有未执行的Message且匹配Runnable的Message全部移除掉
removeCallbacks()方法分析(重载方法:2个参数)
public final void removeCallbacks(Runnable r, Object token)
{
mQueue.removeMessages(this, r, token);
}
用于将Runnable对象与Object对象同时匹配的所有Message对象,才会从MessageQueue全部移除
1、此处的token可传null,此时该方法与上文中的一个参数的removeCallbacks()方法作用一样
2、传入的Runnable对象、Object对象全部会再传入到MessageQueue的removceMessages()方法,完成消息移除工作
removeCallbacksAndMessages()方法分析
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
用于删除多个Message的方法,只要Message持有的token(一个Object对象)匹配,即会被移除掉消息,而不再管Message对象持有的情况,只判断Message对象持有的token
总结
1、send系列方法提交的Message对象,需要移除的时候,可以选用参数带有what的removeMessages()方法
2、post系列方法提交的Message,需要移除的时候选用参数为Runnable的removeCallbacks()方法
3、上文中removeXXX()方法的第一个参数均是当前Handler对象,说明这些移除方法只是将MessageQueue中对应的Handler发送的消息进行移除操作
4、为一个Handler发送的Message对象,可以指定一个Object对象作为token,将来业务上如果不需要这些Message对象,可以根据token全部移除掉未运行的消息,大佬真贴心
5、被移除的Message都是未得到执行的Message,若已经执行的Message是不会在MessageQueue持有的单链表中出现的