- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Kotlin
android 项目中执行了这段代码,它将记录两条消息。如果我将 token
更改为 Char
或 String
它将仅打印一条消息,这是所需的行为。 Android 中的 java 项目中的相同用例可以正常工作。
val handler = Handler()
//val token1: Long = 1001L
//val token2: Int = 121
val token1: Long = 1001L
val token2: Int = 1002
handler.postAtTime(
{
Log.e("postAtTime 1", " printed 1 ")
handler.removeCallbacksAndMessages(token2)
},
token1,
SystemClock.uptimeMillis() + 2000
)
handler.postAtTime(
{
Log.e("postAtTime 2", " printed 2 ")
},
token2,
SystemClock.uptimeMillis() + 4000
)
我的问题是,为什么在 Kotlin 中,对于 Int
、Long
类型的标记,处理程序不会删除回调?
编辑如果我尝试使用注释值,它会起作用
最佳答案
MessageQueue
中的代码(处理消息删除)是 doing this :
while (p != null && p.target == h
&& (object == null || p.obj == object)) {
// clearing code
}
其中 p
是队列中的消息,p.obj
是与其关联的 token ,object
是您可以选择的 token 。已传入以清除消息。因此,如果您已传入一个 token ,并且它与当前消息的 token 匹配,则该消息将被清除。
问题是它使用引用相等来比较 token - 如果它们不是完全相同的对象,如果您没有传入发布消息的同一 token 实例,则它不匹配并且不会发生任何情况。
当您将 token2
声明为 Int
(这是 Kotlin 自己的“一种原语”),然后将其传递给需要实际对象的方法时,它被装箱为一个Integer
。您会执行两次 - 一次是使用 token 发布消息,一次是使用 token 清除消息。它每次都会创建一个不同的(非引用相等)对象。
您可以通过存储 token 对象并比较它们来测试这一点:
val handler = Handler()
//val token1: Long = 1001L
//val token2: Int = 121
val token1: Long = 1001L
val token2: Int = 1002
var postedToken: Any? = null
var cancelledToken: Any? = null
fun postIt(r: ()->Unit, token: Any, time: Long): Any {
handler.postAtTime(r, token, time)
return token
}
fun cancelIt(token: Any): Any {
handler.removeCallbacksAndMessages(token)
return token
}
postIt(
{
Log.e("postAtTime 1", " printed 1 ")
cancelledToken = cancelIt(token2)
// referential equality, triple-equals!
Log.e("Comparing", "Posted === cancelled: ${postedToken === cancelledToken}")
},
token1,
SystemClock.uptimeMillis() + 2000
)
postedToken = postIt(
{
Log.e("postAtTime 2", " printed 2 ")
},
token2,
SystemClock.uptimeMillis() + 4000
)
E/Comparing: Posted === cancelled: false
至于为什么它可以使用 121 的 Int
,我假设它与 Java 的整数缓存有关。在幕后,Kotlin 代码(如果您执行 Show Bytecode
然后反编译它)正在调用 Integer.valueOf(token2)
。 Here's what the docs say about it :
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
因此调用Integer(number)
将总是创建一个新对象,valueOf(number)
可能创建一个,或者它可能返回一个之前创建的Integer
对象。值 121 将始终返回与之前相同的对象,这就是为什么您会获得与该对象的引用相等性,因此标记匹配。对于较大的数字,您将获得不同的对象(您可以在调试器中检查它们的 ID)
但是为什么它可以在 Java 中运行,而不能在 Kotlin 中运行?我没有使用 Java 进行测试,但缓存的工作方式可能不同,也许编译器能够更智能地为“明确缓存”范围之外的 int
变量重用同一对象。或者,如果您在 Java 代码中将标记定义为 Integer
而不是 int
,那么您将创建一个对象并两次传递它,因此始终会这样匹配。
无论如何,呃,这是很多背景知识,可以尝试帮助您找出它为什么会损坏!简而言之,不要这样做,不要让它自动装箱,创建一个 token 对象并保留对它的引用,以便稍后可以再次传递相同的实例;)
(这也适用于String
- Java有一个字符串池,如果你声明一个字符串文字两次,它会重用同一个对象,但它可能不会,所以将 String
分配给变量更安全,然后您就知道它始终是同一个对象)
关于未删除 token 类型 Int 或 Long 的 Android 处理程序回调 (*Kotlin),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62405834/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!