将Handler改成WeakHandler弱引用持有Context以后,新的问题来了,做了延迟操作以后关闭Activity,作为严谨的(强迫症)程序猿,我们还是应该手动去清除handler可能执行的延迟任务Message。有没有办法每次页面生命周期OnPause或者OnDestory的时候自动帮我们完成这个清理呢?这个时候Lifecycle这样的好东西就能帮我们实现这个愿望了!
//重点1:首先记得把WeakHandler继承LifecycleObserver ,这样我们就能观察引用的生命周期了
public class WeakHandler<T extends WeakHandler.WeakHandlerCallBack> extends Handler implements LifecycleObserver {
//新增一个记录我们发送消息的容器用于回收可能存在的延迟任务
private Set<Integer> msgList = new HashSet<>();
public WeakHandler(T t) {
this.weakReference = new WeakReference<>(t);
//重点2:在这里设置生命周期观察
if(weakReference.get() != null && weakReference.get() instanceof LifecycleOwner){
((LifecycleOwner) weakReference.get()).getLifecycle().addObserver(this);
}
}
/**重点3:通过源码我们发现,所有sendMessage,以及Post任务最终都是通过这个函数发出去的,
*我们重写这个函数即可记录所有参与发送的延迟任务(为了安全起见,
*我们把所有发送过得任务都记录下来)
*/
@Override
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
/**实际开发中,如果你的项目页面发射的数据比较多(个人感觉不会太多,所有记录了全部数据),
*可以加上uptimeMillis>0这个过滤条件,另外Post掉的Runner消息也可以采用一样
*的手段在这里记录,然后再后续移除里进行Remove操作,我就不写了*/
if(msg != null){
msgList.add(msg.what);
}
return super.sendMessageAtTime(msg, uptimeMillis);
}
/**重点4:注册生命周期ON_STOP观察者
*这样在我们的引用页面调用OnStop的时候我们就能收到信息做remove处理了,很简单吧!
*同理,有些页面我们不想在OnStop处理,而是需要在OnDestory处理,
*那我们只需要注册ON_DESTORY然后进行对应的处理就可以了
*/
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop(@NotNull LifecycleOwner owner){
LogW.i("WeakHandler LifecycleOwner["+owner+"] onStop");
cleanMsgQuee();
}
//这里也能处理Post任务,自行参考这个就可以搞定了
public synchronized void cleanMsgQuee(){
if(msgList != null && msgList.size() > 0){
Iterator<Integer> iterator = msgList.iterator();
while (iterator.hasNext()) {
Integer what = iterator.next();
if(what != null){
removeMessages(what);
iterator.remove();
}
LogW.i("--->>> cleanMsgQuee remove:"+what);
}
}
}
}
整个实现是不是贼简单,hmm,这下可以直接无脑初始化以后调用了,再也不用担心忘记回收Message的问题了!其实这里面还有可以优化的地方,比如重复发送信息如何记录,以及已经完成的任务应该及时去掉,我这里主要提供一个思路,要是有兴趣的可以深入优化一下!
网友评论