gpt4 book ai didi

android - 线程中的 Kotlin runnable 使用的值与传递的值不同

转载 作者:行者123 更新时间:2023-11-29 19:03:19 27 4
gpt4 key购买 nike

我正在尝试在 Android 上运行一个线程,代码如下:

    override fun onTouchEvent(event: MotionEvent?): Boolean {
Log.d("CustomImage", " touched : ${event!!.x}, ${event.y}")
Thread(Runnable {
if(threadRunning) {
return@Runnable
}
threadRunning = true
consumeTouchEvent(event)
}).start()


return super.onTouchEvent(event)
}

private fun consumeTouchEvent(event: MotionEvent) {
Log.d("CustomImage", " consumeTouchEvent x,y : ${event.x}, ${event.y}")
Thread.sleep(1000) //long running task
threadRunning = false
}

这是我触摸 View 后的相应日志:

01-03 00:17:05.654 8122-8122/me.exp D/CustomImage:  touched : 960.0, 299.0
01-03 00:17:05.656 8122-8250/me.exp D/CustomImage: consumeTouchEvent x,y : 960.0, 509.0

很明显,触摸事件的“Y”值是 299.0,但在 consume 方法中,它被更新为 509。

我能想到的一个可能的解释是,当我触摸屏幕时会触发多个触摸事件,并且 consumeTouchEvent() 中记录的内容是稍后的值 - 但在那种情况下,onTouchEvent( ) 应该记录所有触摸值。

如果我在不生成新线程的情况下运行 consumeTouchEvent(),这个问题就会消失。

最佳答案

Android framework may reuse instances of MotionEvent to avoid heap pollution and excessive garbage collection . recycle方法特别用于将 event 标记为可立即重用:

Recycle the MotionEvent, to be re-used by a later caller. After calling this function you must not ever touch the event again.

在您创建的 Runnable 有机会执行之前,onTouchEvent 已经返回,因此 Android 已经重用了 MotionEvent 实例。

您可以 obtain您自己的副本,以便像这样进行处理:

val myEvent = MotionEvent.obtain(event)
// do some work
myEvent.recycle()

您的示例将如下所示:

val myEvent = MotionEvent.obtain(event)
thread {
if(threadRunning) {
return@Runnable
}
threadRunning = true
consumeTouchEvent(myEvent)
myEvent.recycle()
}
return super.onTouchEvent(event)

关于android - 线程中的 Kotlin runnable 使用的值与传递的值不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48072263/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com