在线程中运行的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 }
触摸视图后,这是相应的日志:
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,但是在消费方法中,它被更新为509。
我可以想到的一个可能的解释是,当我触摸屏幕时触发多个触摸事件,并且consumeTouchEvent()
是稍后的值 – 但是在这种情况下, onTouchEvent()
应该记录所有的触摸值。
如果我不运行一个新的线程运行consumeTouchEvent()
这个问题就消失了。
Android框架可以重用MotionEvent
实例,以避免堆积污染和垃圾收集 。 特别是使用recycle
方法将event
标记为立即可用于重用:
回收MotionEvent,以供稍后调用者重新使用。 调用此函数后,您不能再次触摸该事件。
在您创建的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)
- 在Kotlin的RecyclerView适配器的内部类中访问外部类的成员的最佳方法是什么?
- Android工作室插件ID:’kotlin-android-extensions’
- Kotlin lateinit属性,NPE危险?
- Android Studio 3.0.1(错误:’java’插件已被应用,但与Android插件不兼容。)
- android.widget.Switch – 开/关事件监听器?
- 如何绕过Kotlin上的NetworkOnMainThreadException
- 如何使用kotlin将layoutmanager设置为RecycleView
- 无法在kotlin`whenexpression式中使用string.contains()
- Kotlin中的房间持久性库实现(Gradle错误)