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

相关推荐
梦里不知身是客112 分钟前
datax如何做增量导入
android
算法如诗1 小时前
**MATLAB R2025a** 环境下,基于 **双向时间卷积网络(BITCN)+ 双向长短期记忆网络(BiLSTM)** 的多特征分类预测完整实现
开发语言·网络·matlab
k09331 小时前
在组件外(.js文件)中使用pinia的方法2--在http.js中使用pinia
开发语言·javascript·http
我是好小孩1 小时前
【Android】RecyclerView的高度问题、VH复用概念、多子项的实现;
android·java·网络
4Forsee1 小时前
【Android】模板化解决复杂场景的滑动冲突问题
android·java·rpc
彭同学学习日志1 小时前
解决 Android Navigation 组件导航栏配置崩溃:从错误到实现的完整指南
android·kotlin
法的空间1 小时前
让 Flutter 资源管理更智能
android·flutter·ios
二川bro1 小时前
第44节:物理引擎进阶:Bullet.js集成与高级物理模拟
开发语言·javascript·ecmascript
中文Python1 小时前
小白中文Python-双色球LSTM模型出号程序
开发语言·人工智能·python·lstm·中文python·小白学python
越努力越幸运5081 小时前
JavaScript进阶篇垃圾回收、闭包、函数提升、剩余参数、展开运算符、对象解构
开发语言·javascript