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,让它加一个类似的提示:

相关推荐
2501_94009402几秒前
CHDroid 安卓上的游戏ROM CHD格式转换工具软件 游戏ROM容量压缩
android·游戏
青衫码上行10 分钟前
【Java Web学习 | 第九篇】JavaScript(3) 数组+函数
java·开发语言·前端·javascript·学习
jf加菲猫12 分钟前
第1章 认识Qt
开发语言·c++·qt·ui
猪哥帅过吴彦祖12 分钟前
Flutter 从入门到精通:状态管理入门 - setState 的局限性与 Provider 的优雅之道
android·flutter·ios
铅笔小新z20 分钟前
深入理解C语言内存管理:从栈、堆到内存泄露与悬空指针
c语言·开发语言
m0_4955627825 分钟前
Swift-snapKit使用
开发语言·elasticsearch·swift
用户693717500138426 分钟前
Kotlin 协程 快速入门
android·后端·kotlin
金鸿客27 分钟前
用Compose实现一个Banner轮播组件
android
狂团商城小师妹33 分钟前
JAVA国际版同城服务同城信息同城任务发布平台APP源码Android + IOS
android·java·ios
q***188439 分钟前
搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
开发语言·后端·golang