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 分钟前
62. 不同路径
开发语言·数据结构·算法·leetcode·职场和发展·深度优先
栗子~~17 分钟前
hardhat 单元测试时如何观察gas消耗情况
开发语言·单元测试·区块链·智能合约
The hopes of the whole village19 分钟前
Matlab FFT分析
开发语言·matlab
xiaoshiquan120622 分钟前
Android Studio里,SDK Manager显示不全问题
android·ide·android studio
兰文彬27 分钟前
n8n 2.x版本没有内嵌Python环境
开发语言·python
yiyaozjk30 分钟前
Go基础之环境搭建
开发语言·后端·golang
谁动了我的代码?37 分钟前
VNC中使用QT的GDB调试,触发断点时与界面窗口交互导致整个VNC冻结
开发语言·qt·svn
We་ct1 小时前
LeetCode 212. 单词搜索 II:Trie+DFS 高效解法
开发语言·算法·leetcode·typescript·深度优先·图搜索算法·图搜索
OxyTheCrack1 小时前
【C++】简述main函数中的argc与argv
开发语言·c++
历程里程碑1 小时前
Linux 49 HTTP请求与响应实战解析 带http模拟实现源码--万字长文解析
java·开发语言·网络·c++·网络协议·http·排序算法