handler.removeCallbacksAndMessages不起作用?什么鬼

2,237 阅读1分钟

handler.removeCallbacksAndMessages不起作用?什么鬼

1.背景介绍

当我用百度导航的时候

 BaiduNaviManagerFactory.getRoutePlanManager().routePlanToNavi(
                list,
                IBNRoutePlanManager.RoutePlanPreference.ROUTE_PLAN_PREFERENCE_DISTANCE_FIRST,
                bundle,
                handler
            )


 private val handler: Handler = object : Handler(Looper.getMainLooper()){
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                IBNRoutePlanManager.MSG_NAVI_ROUTE_PLAN_START -> {

                }
                IBNRoutePlanManager.MSG_NAVI_ROUTE_PLAN_SUCCESS -> {

                }
                IBNRoutePlanManager.MSG_NAVI_ROUTE_PLAN_FAILED -> {
                    "计算路程失败".showErrorToasty()
                }
                IBNRoutePlanManager.MSG_NAVI_ROUTE_PLAN_TO_NAVI->{
                    Timber.e("算路成功")
                
                    NavigationUtils.goGuideActivity()
                }
                else -> {
                }
            }
        }
    }

自然在ondestory()需要加上

handler.removeCallbacksAndMessages(null)

问题出现了:正在算路的时候,在finish当前页面的时候

2021-01-29 10:32:43.942 26867-26867/com.yicheche.driverapp E/HotOrderActivityonDestroy:移除handler2021012910:33:07.5912686726867/com.yicheche.driverappE/HotOrderActivityonDestroy: 移除handler 2021-01-29 10:33:07.591 26867-26867/com.yicheche.driverapp E/HotOrderActivityhandler: 算路成功

发生了什么,跟想象的不一样哦,handler消息应该被移除呀

2.分析问题产生原因

1.初步怀疑onDestroy()方法延迟

验证:handler和onDestroy都上日志

结果:果然onDestroy()在页面关闭时偶尔延迟在走此方法,导致handler没有立马移除所有消息

进一步处理:在finish之前移除handler所有消息

override fun onBackPressedSupport() {
        Timber.e("移除算路")
        handler.removeCallbacksAndMessages(null)
        finish()
    }

处理后结果:问题依然出现

2.怀疑handler.removeCallbacksAndMessages有坑?

/** * Remove any pending posts of callbacks and sent messages whose * obj is token. If token is null, * all callbacks and messages will be removed. */

可以看到官方解释当传入null时会删除所有回调和消息

进一步查看,

 void removeCallbacksAndMessages(Handler h, Object object) {
        if (h == null) {
            return;
        }

        synchronized (this) {
            Message p = mMessages;

            // Remove all messages at front.
            while (p != null && p.target == h
                    && (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 && (object == null || n.obj == object)) {
                        Message nn = n.next;
                        n.recycleUnchecked();
                        p.next = nn;
                        continue;
                    }
                }
                p = n;
            }
        }
    }