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

相关推荐
爱的叹息几秒前
Java虚拟机(JVM)家族发展史及版本对比
java·开发语言·jvm
IT技术图谱11 分钟前
【绝非标题党】网络监听新姿势:APT编译时注解实现高扩展框架
android·面试·架构
RichardLai8823 分钟前
[Flutter 基础] - Flutter基础组件 - Text
android·flutter
姜行运35 分钟前
数据结构【树和二叉树】
android·数据结构·算法·c#
苏州向日葵40 分钟前
C#学习知识点记录
开发语言·学习·c#
努力学习的小廉1 小时前
【C++】 —— 笔试刷题day_23
开发语言·c++
居然是阿宋1 小时前
Kotlin函数体详解:表达式函数体 vs 代码块函数体——使用场景与最佳实践
java·开发语言·kotlin
小钊(求职中)1 小时前
Java后端开发面试题(含答案)
java·开发语言·后端·面试
万岳软件开发小城1 小时前
基于PHP+Uniapp的互联网医院源码:电子处方功能落地方案
开发语言·uni-app·php·软件开发·互联网医院系统源码·智慧医院app
东风西巷1 小时前
Control Center安卓版:自定义控制中心,提升手机操作体验
android·智能手机·性能优化·软件需求