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

标签 android kotlin

我正在尝试在 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/

相关文章:

javascript - 在 Android Webview 中嵌入 Facebook 帖子

android - getColumnIndex(_ID) 返回零,getlong(getColumnIndex(_ID)) = 正确值

android - 如何实现延迟交付 (XEP-203) Smack

android - Kotshi 问题 - Unresolved KotshiApplicationJsonAdapterFactory 引用

java - 出现致命异常无法理解原因

android - Kotlin-初始化SharedPreferences

kotlin - Gradle 扩展 : can plain Kotlin types be used instead of Property<T> for properties with simple values?

android - java.lang.NoClassDefFoundError : android. databinding.DataBinderMapperImpl 运行 Espresso 测试时

firebase - 如何从 Firebase 数据库中检索数据并将其存储在 ListArray<Class> 中? - Kotlin

java - 如何在 android 的 gridview 中添加搜索功能?