当前位置:   article > 正文

ANR InputDispatching TimeOut超时判断_input dispatching timed out

input dispatching timed out

InputDispatching超时判断

android-9.0.0_r8

InputReader\InputDispatcher初始化,及其线程启动

JNI涉及java层和C/C++层,ANR超时判断在C/C++层
在这里插入图片描述

InputDispatching

Input事件超时主要是事件分发超时,从标题就有提示。
InputDispatcherThread是InputDispatcher的notifyMotion函数唤醒,执行InputDispatcherThread的threadLoop函数
dispatchOnceInnerLocked开始计时,handleTargetsNotReadyLocked里进行判断超时。
在这里插入图片描述

InputDispatcher::dispatchOnceInnerLocked()

在派发事件时,dispatchKeyLocked()和dispatchMotionLocked(), 需要找到当前的焦点窗口,焦点窗口才是最终接收事件的地方,找窗口的过程就会判断是否已经发生了ANR。

1、当前时间,ANR计时的起点
在这里插入图片描述
2、当分发被冻结,则不再处理超时和分发事件的工作
在这里插入图片描述
3、如果isAppSwitchDue为true,说明没有及时响应HOME键等操作,则抢占分发,丢弃其他所有即将要处理的事件。
在这里插入图片描述
4、mInboundQueue不为空,则取出头部的事件,放入mPendingEvent变量;并重置ANR时间
在这里插入图片描述
5、根据EventEntry的type类型分别处理,比如按键调用dispatchKeyLocked分发事件
在这里插入图片描述
6、执行完成(done)的处理。根据dropReason(默认DROP_REASON_NOT_DROPPED不处理)来决定是否丢失事件;releasePendingEventLocked 释放当前正在处理的事件(即mPendingEvent); 强制立刻执行轮询LONG_LONG_MIN
在这里插入图片描述

InputDispatcher::checkWindowReadyForMoreInputLocked()

在这里插入图片描述

ANR输出相关原因
在这里插入图片描述

InputDispatching超时判断

int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
        const EventEntry* entry,
        const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputWindowHandle>& windowHandle,
        nsecs_t* nextWakeupTime, const char* reason) {
    if (applicationHandle == NULL && windowHandle == NULL) {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
#if DEBUG_FOCUS
            ALOGD("Waiting for system to become ready for input.  Reason: %s", reason);
#endif
            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
            mInputTargetWaitStartTime = currentTime;
            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
            mInputTargetWaitTimeoutExpired = false;
            mInputTargetWaitApplicationHandle.clear();
        }
    } else {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
#if DEBUG_FOCUS
            ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).c_str(),
                    reason);
#endif
            nsecs_t timeout;
            if (windowHandle != NULL) {
                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
            } else if (applicationHandle != NULL) {
                timeout = applicationHandle->getDispatchingTimeout(
                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
            } else {
                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
            }

            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
            mInputTargetWaitStartTime = currentTime;
            mInputTargetWaitTimeoutTime = currentTime + timeout;
            mInputTargetWaitTimeoutExpired = false;
            mInputTargetWaitApplicationHandle.clear();

            if (windowHandle != NULL) {
                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
            }
            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
                mInputTargetWaitApplicationHandle = applicationHandle;
            }
        }
    }

    if (mInputTargetWaitTimeoutExpired) {
        return INPUT_EVENT_INJECTION_TIMED_OUT;
    }

    if (currentTime >= mInputTargetWaitTimeoutTime) {
        onANRLocked(currentTime, applicationHandle, windowHandle,
                entry->eventTime, mInputTargetWaitStartTime, reason);

        // Force poll loop to wake up immediately on next iteration once we get the
        // ANR response back from the policy.
        *nextWakeupTime = LONG_LONG_MIN;
        return INPUT_EVENT_INJECTION_PENDING;
    } else {
        // Force poll loop to wake up when timeout is due.
        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
            *nextWakeupTime = mInputTargetWaitTimeoutTime;
        }
        return INPUT_EVENT_INJECTION_PENDING;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

currentTime >= mInputTargetWaitTimeoutTime超时判断,执行onANRLocked
1、currentTime是指执行dispatchOnceInnerLocked方法体的起点
2、mInputTargetWaitTimeoutTime = currentTime + timeout默认超时时间是五秒DEFAULT_INPUT_DISPATCHING_TIMEOUT
在这里插入图片描述
3、mInputTargetWaitCause等于INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY(应用没有准备就绪),而前面resetANRTimeoutsLocked()过程是唯一用于重置等待理由的地方。可见,ANR时间区间是从dispatchOnceInnerLocked方法体的起点,直到下次执行handleTargetsNotReadyLocked()方法的这段应用未准备就绪的时间段,该时间段是否超过5s来决定是否触发ANR。

ANR log输出

JNI层
在这里插入图片描述
java层
在这里插入图片描述
ANR service TimeOut 超时判断ANR Broadcast TimeOut 超时判断一样使用AppErrors.appNotResponding最终输出Log
在这里插入图片描述

感谢

ANR机制以及问题分析
Input系统—ANR原理分析
Input系统—InputDispatcher线程
Android输入系统(三)InputReader的加工类型和InputDispatcher的分发过程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/204108
推荐阅读
相关标签
  

闽ICP备14008679号