N久没有更新博客了,先发一篇备忘录里缓存的问题解决记录吧,24年要重新开始努力~
首先回忆一波知识点
Handler -> Looper -> MessageQueue
hander持有looper,looper和线程绑定,并且持有一个消息队列MQ
那么,每次 new Handler的时候提供一个相同的Looper,是否可以remove前一个添加到MQ的Message
demo
// 回掉线程
var cacheRunnable: Runnable? = null
/**
* 1秒内顶多执行一次线程
*/
fun function(item: BEAN?) {
// 移除线程
if (cacheRunnable != null) {
cacheRunnable?.let { Handler(Looper.getMainLooper()).removeCallbacks(it) }
}
// 初始化线程
cacheRunnable = Runnable {
handleData(item)
}
// 一秒后执行线程
cacheRunnable?.let { Handler(Looper.getMainLooper()).postDelayed(it, 1000L) }
}
答案是不可以的
Handler:
/**
* Remove any pending posts of Runnable r that are in the message queue.
*/
public final void removeCallbacks(@NonNull Runnable r) {
mQueue.removeMessages(this, r, null);
}
MessageQueue:
void removeMessages(Handler h, Runnable r, Object object) {
if (h == null || r == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.callback == r
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
可以看到,MQ是通过单项列表管理的Message,removeMessage的时候,会同时比对target(Handler)和 callback(Runnable),所以每次去new Handler的方案是无效的。