kotlin android Handler removeCallbacks runnable不生效的一种可能

android Handler无法移除runnable。

比较老的解释就是因为messageQueue已经即将执行的不能被取消,这种我们很好理解它, 因为他已经在跑了,自然无法移掉。

但是在kotlin下有个大坑。

赶快来全局搜索检查你的removeCallbacks吧!

kotlin 复制代码
    private val connectRunnable = {
        //...
        connect()
        //...
    }

 mainHandler.removeCallbacks(connectRunnable)
 if (status == 133) {
    	postMainHandler(500, connectRunnable)
         return
     }

     if (xxxxx) {
         if (xxxx) {
             postMainHandler(15000, connectRunnable)
         } else {
             postMainHandler(8000, connectRunnable)
         }
     } else {
        //....
     }

看着挺正常对吧?这是因为kotlin认为,Runnable等价于 ()->Unit. 坑就这里。它会帮你把()->unit函数转成Runnable传过去。

接下来我们来看看是咋么回事:

Tools-》kotlin-》字节码-》decompile:
可以看到箭头函数会被编译成Function对象。然后就尴尬了:

不用我多解释了吧。明白了吧。

kotlin并非专为android设计。编译器把()->unit函数当做了Runnable,一般情况确实是可以通过function和lambda包裹转变。但是,Android Handler移除就要求的是同一个对象。removeCallbacks的Runnable并非你postDelay的runnable。而从IDEA上是看不出来差异的。

所以改成申明为Runnable

java 复制代码
    private val connectRunnable = Runnable{
       xxxx
    }

我也会上报给google,让它加一个类似的提示:

相关推荐
暗碳几秒前
安卓usb摄像头/采集卡专用软件
android
李少兄2 分钟前
在 Linux 中精准查找名为 `xxx` 的文件或目录路径
android·linux·adb
2201_757830873 分钟前
反射的概念
java·开发语言
2501_916008894 分钟前
App 上架服务行业的实际工作流程与工具选择 从人工代办到跨平台自动化的转变
android·运维·ios·小程序·uni-app·自动化·iphone
周杰伦_Jay5 分钟前
【Conda 完全指南】环境管理+包管理从入门到精通(含实操示例+表格对比)
开发语言·人工智能·微服务·架构·conda
努力学习的小廉7 分钟前
【QT(一)】—— QT Creator的安装与使用
开发语言·qt
阿巳helloWorld11 分钟前
SpringMVC底层流程解析
java·开发语言
zhimingwen12 分钟前
macOS 上安装与配置apksigner (读取APK签名的工具)
android·macos· sha-1
Jomurphys18 分钟前
设计模式 - 享元模式 Flyweight Pattern
android·设计模式·享元模式
Jomurphys19 分钟前
设计模式 - 组合模式 Composite Pattern
android·设计模式·组合模式