线程中可运行的Kotlin使用的值与通过

时间:2018-01-03 06:27:51

标签: 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
    }

触摸视图后,显示相应的日志:

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' touch事件的值是299.0,但在consume方法中,它被更新为509.

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

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

1 个答案:

答案 0 :(得分:2)

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

  

回收MotionEvent,供以后的调用者重用。调用此功能后,您不能再次触摸该事件。

在您Runnable创建的onTouchEvent有机会执行MotionEvent已经返回之前,Android已重新使用val myEvent = MotionEvent.obtain(event) // do some work myEvent.recycle() 实例。

您可以obtain自己的副本进行处理,如下所示:

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

您的示例将如下所示:

#include <iostream>
#include <fstream>

int main(int argc, char **argv)
{
    std::ifstream is(argv[1]);

    for (;;)
    {
        int x1 = 0, x2 = 0;
        char sep = 0;

        is >> x1;
        is >> sep;
        is >> x2;

        // Validate the data.
        if ((sep != ',') or is.eof()) { break; }

        // Data tests valid, use it however.
        std::cout << "read: " << x1 << sep << x2 << std::endl;
    }
}