android 输入系统如何知道输入事件未被处理,从而导致 anr



我用按钮写一个应用程序,当点击按钮时,会调用以下方法:

    public void click(View view) {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

因此,显然,这将在下一个输入事件到来后导致 anr。我以为这个处理输入事件的点击方法不会导致调用 InputEventReceiver 类中的 finishInputEvent 方法,但我错了,无论点击方法是否返回,仍然会调用 finishInputEvent。 InputEventReceiver 类中的 finishInputEvent 方法如下所示:

    public final void finishInputEvent(InputEvent event, boolean handled) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
        if (mReceiverPtr == 0) {
            Log.w(TAG, "Attempted to finish an input event but the input event "
                    + "receiver has already been disposed.");
        } else {
            int index = mSeqMap.indexOfKey(event.getSequenceNumber());
            if (index < 0) {
                Log.w(TAG, "Attempted to finish an input event that is not in progress.");
            } else {
                int seq = mSeqMap.valueAt(index);
                mSeqMap.removeAt(index);
                nativeFinishInputEvent(mReceiverPtr, seq, handled);
            }
        }
        event.recycleIfNeededAfterDispatch();
    }

我以为 nativeFinishInputEvent 会删除输入系统中队列中的一个项目,这样就不会导致 anr,但现在仍然调用 nativeFinishInputEvent,为什么仍然会导致 anr? 输入系统如何知道输入事件未被处理?

对于给定应用,所有 Android UI 事件都由单个线程处理。通过使该线程进入睡眠状态,您将阻止线程处理进一步的事件,并且系统会检测到队列中存在未处理的事件,因此 ANR。通常,您永远不应该在 UI 线程中睡觉。

最新更新