Android; “Key dispatching timed out …”

ⅰ亾dé卋堺 提交于 2019-12-05 16:53:50

One common cause of the "Key dispatching timed out", which I experienced quite often until digging a little deeper, is holding onto the UI thread - which handles UI events - in the debugger for more than a short amount of time (details below). For instance, if you want to debug code in your event handler, this is potential problem.

For example, if you set a breakpoint in onTouchEvent() of an Activity

class MyActivity extends Activity
{
    public boolean onTouchEvent(MotionEvent me)
    {
        // ** Breakpoint ** 
        // Code you wish to debug
    }
}

... and you hold on to this thread (UI):

After 5 seconds you will get this warning: Key dispatching timed out sending to com.hos/com.hos.MyActivity ... null to Window ...

After 20 seconds you will get: Key dispatching timed out sending to com.hos/com.hos.MyActivity ... null to Window ... Continuing to wait for key to be dispatched

After 35 seconds you will get: Key dispatching timed out sending to com.hos/com.hos.MyActivity ... null to Window ... timed out expired process next Key & find new target

At this point, not only is the application frozen but so is the phone. Quite often I need to wait for the ANR and sometimes hard restart the phone.

So one simple answer is don't hold on to the UI thread, whether it be with the debugger or with time-expensive code.

=============

Regarding synchronization, this is a very similar problem. In this example, an onTouchEvent() may have to wait for the population of a non-thread-safe shared resource. In which case it may timeout if population is occurring during the touch event.

class MyActivity extends Activity
{
    private static ArrayList<Object> m_alShared = new ArrayList<Object>();

    public boolean onTouchEvent(MotionEvent me)
    {
        synchronized(this)
        {
            // accessed shared resource.
            m_alShared.get(?);
        }
    }

    public void methodCalledByBackgroundThread()
    {
        synchronized(this)
        {
            // populate shared resource for more than 35 seconds
            while (/* time < 35 seconds */)
                m_alShared.add(?);
        }
    }
}

Personally, I choose to not synchronize or use any "wait" function on the UI thread. Or if you need to, make sure it's quick. It's a race condition waiting to happen. Especially if it affects not only your app, but your phone.

i.e. I might opt for the following solution and synchronize each add.

    public void methodCalledByBackgroundThread()
    {
        while (/* time < 35 seconds */)
        {
            synchronized(this)
            {
                // populate shared resource for more than 35 seconds
                m_alShared.add(?);
            }
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!