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

相关推荐
喜欢流萤吖~5 分钟前
SpringBoot 异步处理与线程池实战
java·开发语言
c++逐梦人6 分钟前
C++ RAII流式日志库实现
开发语言·c++
t***5446 分钟前
还有哪些设计模式适合现代C++
开发语言·c++·设计模式
Dshuishui6 分钟前
学习一下 Python 包管理器 uv
开发语言·python·uv
Wave8457 分钟前
C++ 面向对象基础:类、访问权限,构造函数,析构函数
开发语言·c++
t***5448 分钟前
如何在现代C++项目中有效应用这些设计模式
开发语言·c++·设计模式
野生技术架构师9 分钟前
2026年Java面试题集锦(含答案)
java·开发语言·面试
lolo大魔王10 分钟前
Go语言的defer语句和Test功能测试函数
开发语言·后端·golang
XiaoLeisj20 分钟前
Android 短视频播放详情页实战:从播放器模块拆分、Media3 与 FlowHelper 接入,到 ViewPager 高度适配和详情数据联动
android·okhttp·音视频·架构设计·flowhelper
无限进步_25 分钟前
【C++】私有虚函数与多态:访问权限不影响动态绑定
开发语言·c++·ide·windows·git·算法·visual studio