当前位置: 首页 > news >正文

什么是网站前台有哪些网站可以做青旅义工

什么是网站前台,有哪些网站可以做青旅义工,网站后台清空,哪些网站可以做兼职1 ANR的检测逻辑有两个参与者: 观测者A和被观测者B#xff0c;当然#xff0c;这两者是不在同一个线程中的。2 A在调用B中的逻辑时#xff0c;同时在A中保存一个标记F#xff0c;然后做个延时操作C#xff0c;延时时间设为T#xff0c;这一步称为: 埋雷 。3 B中的逻辑如果…1 ANR的检测逻辑有两个参与者: 观测者A和被观测者B当然这两者是不在同一个线程中的。2 A在调用B中的逻辑时同时在A中保存一个标记F然后做个延时操作C延时时间设为T这一步称为: 埋雷 。3 B中的逻辑如果被执行到就会通知A去清除标记F并且通知A解除C这一步称为: 拆雷 。4 如果C没被拆除那么在时间T后就会被触发就会去检测标记F是否还在如果在就说明B没有在指定的时间T内完成那么就提示B发生了ANR这一步称为: 爆雷 。5 由于A和B是在不同线程中的所以B即使死循环也不会影响C的检测过程。 所以我们可以将ANR更精炼的总结为: 埋雷、拆雷和爆雷三个步骤 。 InputDispatching Timeout 输入事件包括按键和触屏事件在5秒内无响应就会弹出 ANR 提示框供用户选择继续等待程序响应或者关闭这个应用程序也就是杀掉这个应用程序的进程。输入超时类的 ANR 可以细分为以下两类 1处理消息超时 这一类是指因为消息处理超时而发生的 ANR在 log会看到 “Input dispatching timed out (Waiting because the focused window has not finished processing the input events that were previously delivered to it.)” 2无法获取焦点 这一类通常因为新窗口创建慢或旧窗口退出慢而造成窗口无法获得焦点从而发生 ANR典型 Log “Reason: Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.” 这里不分析没有焦点的情形只分析处理消息超时流程 在 input子系统中正常逻辑是InputDispatcher 负责将输入事件分发给 UI 主线程。UI主线程接收到输入事件后使用 InputConsumer 来处理事件。经过一系列的 InputStage 完成事件分发后执行finishInputEvent() 方法来告知 InputDispatcher 事件已经处理完成。InputDispatcher 中使用handleReceiveCallback() 方法来处理 UI 主线程返回的消息最终将 dispatchEntry事件从等待队列中移除。 http://aospxref.com/android-13.0.0_r3/xref/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp 3975 void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { // 打开下列的开关会打印对应的log 3976 if (DEBUG_INBOUND_EVENT_DETAILS) { 3977 ALOGD(notifyMotion - id% PRIx32 eventTime% PRId64 , deviceId%d, source0x%x, 3978 displayId% PRId32 , policyFlags0x%x, 3979 action0x%x, actionButton0x%x, flags0x%x, metaState0x%x, buttonState0x%x, 3980 edgeFlags0x%x, xPrecision%f, yPrecision%f, xCursorPosition%f, 3981 yCursorPosition%f, downTime% PRId64, 3982 args-id, args-eventTime, args-deviceId, args-source, args-displayId, 3983 args-policyFlags, args-action, args-actionButton, args-flags, args-metaState, 3984 args-buttonState, args-edgeFlags, args-xPrecision, args-yPrecision, 3985 args-xCursorPosition, args-yCursorPosition, args-downTime); 3986 for (uint32_t i 0; i args-pointerCount; i) { 。。。。 4047 // Just enqueue a new motion event.// 创建 MotionEntry 对象 4048 std::unique_ptrMotionEntry newEntry 4049 std::make_uniqueMotionEntry(args-id, args-eventTime, args-deviceId, 4050 args-source, args-displayId, policyFlags, 4051 args-action, args-actionButton, args-flags, 4052 args-metaState, args-buttonState, 4053 args-classification, args-edgeFlags, 4054 args-xPrecision, args-yPrecision, 4055 args-xCursorPosition, args-yCursorPosition, 4056 args-downTime, args-pointerCount, 4057 args-pointerProperties, args-pointerCoords); 4058 4059 if (args-id ! android::os::IInputConstants::INVALID_INPUT_EVENT_ID 4060 IdGenerator::getSource(args-id) IdGenerator::Source::INPUT_READER 4061 !mInputFilterEnabled) { 4062 const bool isDown args-action AMOTION_EVENT_ACTION_DOWN; 4063 mLatencyTracker.trackListener(args-id, isDown, args-eventTime, args-readTime); 4064 } 4065 // 将 MotionEntry 事件保存到 mInboundQueue 队列中如果保存之前 mInboundQueue是为空的则 needWake 为true。 4066 needWake enqueueInboundEventLocked(std::move(newEntry)); 4067 mLock.unlock(); 4068 } // release lock 4069 // 这里分析直接去唤醒inputdispatcher 线程 4070 if (needWake) { 4071 mLooper-wake(); 4072 } 4073 }InputDispatcher 是个线程会循环执行 dispatchOnce 方法 602 void InputDispatcher::dispatchOnce() { 603 nsecs_t nextWakeupTime LONG_LONG_MAX;// 局部空间获取同步锁 604 { // acquire lock 605 std::scoped_lock _l(mLock); 606 mDispatcherIsAlive.notify_all(); 607 608 // Run a dispatch loop if there are no pending commands. 609 // The dispatch loop might enqueue commands to run afterwards.// 如果没有 mCommandQueue 没有 command 命令的话 // 则执行 dispatchOnceInnerLocked获取到下一次唤醒的时间nextWakeupTime // 1如果有motion 事件调用 dispatchOnceInnerLocked 方法 610 if (!haveCommandsLocked()) { 611 dispatchOnceInnerLocked(nextWakeupTime); 612 } 613 // 执行command 命令如果有的话直接返回 true然后马上唤醒线程 616 if (runCommandsLockedInterruptable()) { 617 nextWakeupTime LONG_LONG_MIN; 618 } 619 // 处理anr 或者获取到下一次anr 的时间 // 2获取超时anr 的时间processAnrsLocked 622 const nsecs_t nextAnrCheck processAnrsLocked(); 623 nextWakeupTime std::min(nextWakeupTime, nextAnrCheck); 624 625 // We are about to enter an infinitely long sleep, because we have no commands or 626 // pending or queued events// 如果唤醒时间为最大则表明没有input 事件是idle 空闲状态 627 if (nextWakeupTime LONG_LONG_MAX) { 628 mDispatcherEnteredIdle.notify_all(); 629 } 630 } // release lock 631 632 // Wait for callback or timeout or wake. (make sure we round up, not down) 633 nsecs_t currentTime now(); // 获取到唤醒线程的时间 // 调用 mLooper-wake 函数也可以唤醒线程 634 int timeoutMillis toMillisecondTimeoutDelay(currentTime, nextWakeupTime); 635 mLooper-pollOnce(timeoutMillis); 636 }1如果有motion 事件调用 dispatchOnceInnerLocked 方法 718 void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { 719 nsecs_t currentTime now(); 。。。 // 初始 mPendingEvent 为null 746 if (!mPendingEvent) { // 前面notifymotion 增加了 mInboundQueue 747 if (mInboundQueue.empty()) { 。。。 770 } else { 771 // Inbound queue has at least one entry. // 这里去获取到motion 事件 772 mPendingEvent mInboundQueue.front(); 773 mInboundQueue.pop_front(); 774 traceInboundQueueLengthLocked(); 775 } 776 777 // Poke user activity for this event. 778 if (mPendingEvent-policyFlags POLICY_FLAG_PASS_TO_USER) { 779 pokeUserActivityLocked(*mPendingEvent); 780 } 781 } 。。。 798 switch (mPendingEvent-type) { 868 case EventEntry::Type::MOTION: { 869 std::shared_ptrMotionEntry motionEntry 870 std::static_pointer_castMotionEntry(mPendingEvent); 871 if (dropReason DropReason::NOT_DROPPED isAppSwitchDue) { 872 dropReason DropReason::APP_SWITCH; 873 } 874 if (dropReason DropReason::NOT_DROPPED isStaleEvent(currentTime, *motionEntry)) { 875 dropReason DropReason::STALE; 876 } 877 if (dropReason DropReason::NOT_DROPPED mNextUnblockedEvent) { 878 dropReason DropReason::BLOCKED; 879 } // dispatchMotionLocked 方法去分发motion 事件 880 done dispatchMotionLocked(currentTime, motionEntry, dropReason, nextWakeupTime); 881 break; 882 } 。。。 // 一般是返回true表示分发motion 事件到应用了 902 if (done) { 903 if (dropReason ! DropReason::NOT_DROPPED) { 904 dropInboundEventLocked(*mPendingEvent, dropReason); 905 } 906 mLastDropReason dropReason; 907 // 返回true则重新设置 mPendingEvent 为null 908 releasePendingEventLocked(); // 设置 nextWakeupTime 为最小马上唤醒 909 *nextWakeupTime LONG_LONG_MIN; // force next poll to wake up immediately 910 } 911 }// dispatchMotionLocked 方法去分发motion 事件 1634 bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptrMotionEntry entry, 1635 DropReason* dropReason, nsecs_t* nextWakeupTime) { // 会打印对应的trace 1636 ATRACE_CALL(); 。。。 1652 const bool isPointerEvent isFromSource(entry-source, AINPUT_SOURCE_CLASS_POINTER); 1653 1654 // Identify targets. 1655 std::vectorInputTarget inputTargets; 1656 1657 bool conflictingPointerActions false; 1658 InputEventInjectionResult injectionResult; 1659 if (isPointerEvent) { 1660 // Pointer event. (eg. touchscreen)// 去根据xy 的坐标点去找到触摸的 window 1661 injectionResult 1662 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime, 1663 conflictingPointerActions); 。。。 // 增加到全局触摸事件 1687 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry)); 1688 1689 // Dispatch the motion. 1690 if (conflictingPointerActions) { 1691 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, 1692 conflicting pointer actions); 1693 synthesizeCancelationEventsForAllConnectionsLocked(options); 1694 } // 分发event 1695 dispatchEventLocked(currentTime, entry, inputTargets); 1696 return true; 1697 }// 分发event 1753 void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, 1754 std::shared_ptrEventEntry eventEntry, 1755 const std::vectorInputTarget inputTargets) { 1756 ATRACE_CALL(); 1757 if (DEBUG_DISPATCH_CYCLE) { 1758 ALOGD(dispatchEventToCurrentInputTargets); 1759 } 1760 1761 updateInteractionTokensLocked(*eventEntry, inputTargets); 1762 1763 ALOG_ASSERT(eventEntry-dispatchInProgress); // should already have been set to true 1764 1765 pokeUserActivityLocked(*eventEntry); 1766 1767 for (const InputTarget inputTarget : inputTargets) {// 找到对应的窗口的 connection 1768 spConnection connection 1769 getConnectionLocked(inputTarget.inputChannel-getConnectionToken()); 1770 if (connection ! nullptr) { 1771 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget); 1772 } else { 1773 if (DEBUG_FOCUS) { 1774 ALOGD(Dropping event delivery to target with channel %s because it 1775 is no longer registered with the input dispatcher., 1776 inputTarget.inputChannel-getName().c_str()); 1777 } 1778 } 1779 } 1780 }准备分发事件给应用 prepareDispatchCycleLocked 2887 void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, 2888 const spConnection connection, 2889 std::shared_ptrEventEntry eventEntry, 2890 const InputTarget inputTarget) { 2891 if (ATRACE_ENABLED()) { 2892 std::string message 2893 StringPrintf(prepareDispatchCycleLocked(inputChannel%s, id0x% PRIx32 ), 2894 connection-getInputChannelName().c_str(), eventEntry-id); 2895 ATRACE_NAME(message.c_str()); 2896 } 。。。。。 2944 2945 // Not splitting. Enqueue dispatch entries for the event as is. 2946 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget); 2947 }2949 void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime, 2950 const spConnection connection, 2951 std::shared_ptrEventEntry eventEntry, 2952 const InputTarget inputTarget) { 2953 if (ATRACE_ENABLED()) { 2954 std::string message 2955 StringPrintf(enqueueDispatchEntriesLocked(inputChannel%s, id0x% PRIx32 ), 2956 connection-getInputChannelName().c_str(), eventEntry-id); 2957 ATRACE_NAME(message.c_str()); 2958 } 2959 2960 bool wasEmpty connection-outboundQueue.empty(); 2961 // 将触摸事件保存到 outboundQueue 中 2962 // Enqueue dispatch entries for the requested modes. 2963 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2964 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT); 2965 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2966 InputTarget::FLAG_DISPATCH_AS_OUTSIDE); 2967 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2968 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER); 2969 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2970 InputTarget::FLAG_DISPATCH_AS_IS); 2971 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2972 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT); 2973 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 2974 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER); 2975 2976 // If the outbound queue was previously empty, start the dispatch cycle going. 2977 if (wasEmpty !connection-outboundQueue.empty()) { // 开始socket 通信去分发给应用 startDispatchCycleLocked 2978 startDispatchCycleLocked(currentTime, connection); 2979 } 2980 }// 开始socket 通信去分发给应用 startDispatchCycleLocked 3214 void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, 3215 const spConnection connection) { 3216 if (ATRACE_ENABLED()) { 3217 std::string message StringPrintf(startDispatchCycleLocked(inputChannel%s), 3218 connection-getInputChannelName().c_str()); 3219 ATRACE_NAME(message.c_str()); 3220 } 3221 if (DEBUG_DISPATCH_CYCLE) { 3222 ALOGD(channel %s ~ startDispatchCycle, connection-getInputChannelName().c_str()); 3223 } 3224 3225 while (connection-status Connection::Status::NORMAL !connection-outboundQueue.empty()) { 3226 DispatchEntry* dispatchEntry connection-outboundQueue.front(); 3227 dispatchEntry-deliveryTime currentTime; // 获取到应用设置的超时事件一般为 5 秒 3228 const std::chrono::nanoseconds timeout getDispatchingTimeoutLocked(connection); // 设置timeout 的时间 3229 dispatchEntry-timeoutTime currentTime timeout.count(); 。。。 3252 case EventEntry::Type::MOTION: { 3253 const MotionEntry motionEntry static_castconst MotionEntry(eventEntry); 。。。 // socket 通信发送给 应用给到应用去处理了 3285 // Publish the motion event. 3286 status connection-inputPublisher 3287 .publishMotionEvent(dispatchEntry-seq, 3288 dispatchEntry-resolvedEventId, 3289 motionEntry.deviceId, motionEntry.source, 3290 motionEntry.displayId, std::move(hmac), 3291 dispatchEntry-resolvedAction, 3292 motionEntry.actionButton, 3293 dispatchEntry-resolvedFlags, 3294 motionEntry.edgeFlags, motionEntry.metaState, 3295 motionEntry.buttonState, 3296 motionEntry.classification, 3297 dispatchEntry-transform, 3298 motionEntry.xPrecision, motionEntry.yPrecision, 3299 motionEntry.xCursorPosition, 3300 motionEntry.yCursorPosition, 3301 dispatchEntry-rawTransform, 3302 motionEntry.downTime, motionEntry.eventTime, 3303 motionEntry.pointerCount, 3304 motionEntry.pointerProperties, usingCoords); 3305 break; 3306 } 。。。。。 3383 // Re-enqueue the event on the wait queue. // 将触摸事件从 outboundQueue 移除掉 3384 connection-outboundQueue.erase(std::remove(connection-outboundQueue.begin(), 3385 connection-outboundQueue.end(), 3386 dispatchEntry)); 3387 traceOutboundQueueLength(*connection); // 将其增加到 waitQueue 等待队列中 3388 connection-waitQueue.push_back(dispatchEntry); // 如果应用没有die则 将anr 超时时间保存到 mAnrTracker 中还有对应的应用token 3389 if (connection-responsive) { 3390 mAnrTracker.insert(dispatchEntry-timeoutTime, 3391 connection-inputChannel-getConnectionToken()); 3392 } 3393 traceWaitQueueLength(*connection); 3394 } 3395 }2获取超时anr 的时间processAnrsLocked 622 const nsecs_t nextAnrCheck processAnrsLocked(); // nextWakeupTime 由前面的分析返回的是为 LONG_LONG_MIN所以这里的唤醒时间为马上唤醒 623 nextWakeupTime std::min(nextWakeupTime, nextAnrCheck); 670 nsecs_t InputDispatcher::processAnrsLocked() { 671 const nsecs_t currentTime now(); 672 nsecs_t nextAnrCheck LONG_LONG_MAX;// 下列是处理no focus 没有焦点的情况这里不满足 674 if (mNoFocusedWindowTimeoutTime.has_value() mAwaitedFocusedApplication ! nullptr) { 675 if (currentTime *mNoFocusedWindowTimeoutTime) { 676 processNoFocusedWindowAnrLocked(); 677 mAwaitedFocusedApplication.reset(); 678 mNoFocusedWindowTimeoutTime std::nullopt; 679 return LONG_LONG_MIN; 680 } else { 681 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes. 682 nextAnrCheck *mNoFocusedWindowTimeoutTime; 683 } 684 } 685 // 获取到前面保存到anr 的时间即前面当前的时间 timeout 5 秒 687 nextAnrCheck std::min(nextAnrCheck, mAnrTracker.firstTimeout()); // 当前的时间是小于 nextAnrCheck所以返回 nextAnrCheck的时间 688 if (currentTime nextAnrCheck) { // most likely scenario 689 return nextAnrCheck; // everything is normal. Lets check again at nextAnrCheck 690 } 691 692 // If we reached here, we have an unresponsive connection. 693 spConnection connection getConnectionLocked(mAnrTracker.firstToken()); 694 if (connection nullptr) { 695 ALOGE(Could not find connection for entry % PRId64, mAnrTracker.firstTimeout()); 696 return nextAnrCheck; 697 } 698 connection-responsive false; 699 // Stop waking up for this unresponsive connection 700 mAnrTracker.eraseToken(connection-inputChannel-getConnectionToken()); 701 onAnrLocked(connection); 702 return LONG_LONG_MIN; 703 }但是接下有个处理 这里返回时 MIN 的即马上唤醒。所以再走一次线程dispatchOnce 方法 nextWakeupTime std::min(nextWakeupTime, nextAnrCheck); 602 void InputDispatcher::dispatchOnce() { 603 nsecs_t nextWakeupTime LONG_LONG_MAX; 604 { // acquire lock 605 std::scoped_lock _l(mLock); 606 mDispatcherIsAlive.notify_all(); 607 // 这时候没有inboundqueue 了 610 if (!haveCommandsLocked()) { 611 dispatchOnceInnerLocked(nextWakeupTime); 612 } 613 // 也没有cammand 616 if (runCommandsLockedInterruptable()) { 617 nextWakeupTime LONG_LONG_MIN; 618 } 619 // 这里就可以获取到 anr 的时间了 622 const nsecs_t nextAnrCheck processAnrsLocked(); 623 nextWakeupTime std::min(nextWakeupTime, nextAnrCheck); 624 625 // We are about to enter an infinitely long sleep, because we have no commands or 626 // pending or queued events 627 if (nextWakeupTime LONG_LONG_MAX) { 628 mDispatcherEnteredIdle.notify_all(); 629 } 630 } // release lock 631 633 nsecs_t currentTime now(); 634 int timeoutMillis toMillisecondTimeoutDelay(currentTime, nextWakeupTime); // 这里去等待anr 超时的时间 635 mLooper-pollOnce(timeoutMillis); 636 }3排雷过程 // 在inputdispatcher 与应用创建连接的时候会设置socket 通信的callback执行 handleReceiveCallback 方法 5450 Resultstd::unique_ptrInputChannel InputDispatcher::createInputChannel(const std::string name) { 5451 if (DEBUG_CHANNEL_CREATION) { 5452 ALOGD(channel %s ~ createInputChannel, name.c_str()); 5453 } 。。。5475 std::functionint(int events) callback std::bind(InputDispatcher::handleReceiveCallback, 5476 this, std::placeholders::_1, token); 5477 5478 mLooper-addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr); 5479 } // release lock 5480 5481 // Wake the looper because some connections have changed. 5482 mLooper-wake(); 5483 return clientChannel; 5484 }如果应用有发送socket 消息则执行 handleReceiveCallback 方法 int InputDispatcher::handleReceiveCallback(int events, spIBinder connectionToken) {std::scoped_lock _l(mLock); // 通过token 获取到对应的connectionspConnection connection getConnectionLocked(connectionToken);bool notify; // event 不能为 ALOOPER_EVENT_ERROR 或者 ALOOPER_EVENT_HANGUPif (!(events (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {if (!(events ALOOPER_EVENT_INPUT)) {ALOGW(channel %s ~ Received spurious callback for unhandled poll event. events0x%x,connection-getInputChannelName().c_str(), events);return 1;}nsecs_t currentTime now();bool gotOne false;status_t status OK; // 循环操作for (;;) { // 通过socket 获取到消息ResultInputPublisher::ConsumerResponse result connection-inputPublisher.receiveConsumerResponse();if (!result.ok()) {status result.error().code();break;} // 如果result 是 Finished则执行 finishDispatchCycleLockedif (std::holds_alternativeInputPublisher::Finished(*result)) {const InputPublisher::Finished finish std::getInputPublisher::Finished(*result);finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,finish.consumeTime); 。。。 // 设置 gotOne true gotOne true;}if (gotOne) { // finishDispatchCycleLocked 增加了command这里去执行 commandrunCommandsLockedInterruptable();if (status WOULD_BLOCK) {return 1;}}// 如果result 是 Finished则执行 finishDispatchCycleLocked void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,const spConnection connection, uint32_t seq,bool handled, nsecs_t consumeTime) {if (DEBUG_DISPATCH_CYCLE) {ALOGD(channel %s ~ finishDispatchCycle - seq%u, handled%s,connection-getInputChannelName().c_str(), seq, toString(handled));}if (connection-status Connection::Status::BROKEN ||connection-status Connection::Status::ZOMBIE) {return;}// Notify other system components and prepare to start the next dispatch cycle.auto command [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);};postCommandLocked(std::move(command)); }前面 runCommandsLockedInterruptable 方法会去执行 doDispatchCycleFinishedCommand 方法 void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,const spConnection connection, uint32_t seq,bool handled, nsecs_t consumeTime) {// Handle post-event policy actions.std::dequeDispatchEntry*::iterator dispatchEntryIt connection-findWaitQueueEntry(seq);if (dispatchEntryIt connection-waitQueue.end()) {return;}DispatchEntry* dispatchEntry *dispatchEntryIt;const nsecs_t eventDuration finishTime - dispatchEntry-deliveryTime; // 如果应用处理超过 2 秒则会打印下列的日志if (eventDuration SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {ALOGI(%s spent % PRId64 ms processing %s, connection-getWindowName().c_str(),ns2ms(eventDuration), dispatchEntry-eventEntry-getDescription().c_str());} 。。。 // 从等待队列中找到 dispatchEntryIt dispatchEntryIt connection-findWaitQueueEntry(seq);if (dispatchEntryIt ! connection-waitQueue.end()) {dispatchEntry *dispatchEntryIt;connection-waitQueue.erase(dispatchEntryIt);const spIBinder connectionToken connection-inputChannel-getConnectionToken(); // 从anrtracker 中移除这个超时时间和connectionmAnrTracker.erase(dispatchEntry-timeoutTime, connectionToken);if (!connection-responsive) {connection-responsive isConnectionResponsive(*connection);if (connection-responsive) {// The connection was unresponsive, and now its responsive.processConnectionResponsiveLocked(*connection);}}traceWaitQueueLength(*connection);if (restartEvent connection-status Connection::Status::NORMAL) {connection-outboundQueue.push_front(dispatchEntry);traceOutboundQueueLength(*connection);} else {releaseDispatchEntry(dispatchEntry);}}// Start the next dispatch cycle for this connection. // 如果还有下一个事件的话则调用 startDispatchCycleLocked 继续去处理startDispatchCycleLocked(now(), connection); }则下次执行线程的时候由于mAnrTracker移除了对应的conenction则 processAnrsLocked不会触发anr 流程 4爆雷过程 在anr 时间点触发线程执行dispatchOnce然后执行 processAnrsLocked 方法 nsecs_t InputDispatcher::processAnrsLocked() {const nsecs_t currentTime now();nsecs_t nextAnrCheck LONG_LONG_MAX; // 不满足下列的条件if (mNoFocusedWindowTimeoutTime.has_value() mAwaitedFocusedApplication ! nullptr) {if (currentTime *mNoFocusedWindowTimeoutTime) {processNoFocusedWindowAnrLocked();mAwaitedFocusedApplication.reset();mNoFocusedWindowTimeoutTime std::nullopt;return LONG_LONG_MIN;} else {// Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.nextAnrCheck *mNoFocusedWindowTimeoutTime;}}// Check if any connection ANRs are duenextAnrCheck std::min(nextAnrCheck, mAnrTracker.firstTimeout()); // 这里当前的时间点是大于 anr 的时间即前面没有移除if (currentTime nextAnrCheck) { // most likely scenarioreturn nextAnrCheck; // everything is normal. Lets check again at nextAnrCheck}// 执行下列anr 的流程// If we reached here, we have an unresponsive connection.spConnection connection getConnectionLocked(mAnrTracker.firstToken());if (connection nullptr) {ALOGE(Could not find connection for entry % PRId64, mAnrTracker.firstTimeout());return nextAnrCheck;} // 设置应用回复为 falseconnection-responsive false;// Stop waking up for this unresponsive connection // 从anrtracker 中移除防止进入到线程又再次触发anrmAnrTracker.eraseToken(connection-inputChannel-getConnectionToken()); // 走anr 流程onAnrLockedonAnrLocked(connection);return LONG_LONG_MIN; }// 走anr 流程onAnrLocked void InputDispatcher::onAnrLocked(const spConnection connection) {if (connection nullptr) {LOG_ALWAYS_FATAL(Caller must check for nullness);}// Since we are allowing the policy to extend the timeout, maybe the waitQueue// is already healthy again. Dont raise ANR in this situationif (connection-waitQueue.empty()) {ALOGI(Not raising ANR because the connection %s has recovered,connection-inputChannel-getName().c_str());return;} // 从等待队列中获取DispatchEntry* oldestEntry *connection-waitQueue.begin(); // 获取到等待的时间const nsecs_t currentWait now() - oldestEntry-deliveryTime; // 设置input dispatcher 时间分发超时的原因 reasonstd::string reason android::base::StringPrintf(%s is not responding. Waited % PRId64 ms for %s,connection-inputChannel-getName().c_str(),ns2ms(currentWait),oldestEntry-eventEntry-getDescription().c_str());spIBinder connectionToken connection-inputChannel-getConnectionToken(); // 保存到dump 中updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);processConnectionUnresponsiveLocked(*connection, std::move(reason));// Stop waking up for events on this connection, it is already unresponsivecancelEventsForAnrLocked(connection); }processConnectionUnresponsiveLocked 处理anr void InputDispatcher::processConnectionUnresponsiveLocked(const Connection connection,std::string reason) {const spIBinder connectionToken connection.inputChannel-getConnectionToken();std::optionalint32_t pid; // 不满足下列条件if (connection.monitor) {ALOGW(Monitor %s is unresponsive: %s, connection.inputChannel-getName().c_str(),reason.c_str());pid findMonitorPidByTokenLocked(connectionToken);} else {// The connection is a windowALOGW(Window %s is unresponsive: %s, connection.inputChannel-getName().c_str(),reason.c_str());const spWindowInfoHandle handle getWindowHandleLocked(connectionToken);if (handle ! nullptr) {pid handle-getInfo()-ownerPid;}}sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason)); }void InputDispatcher::sendWindowUnresponsiveCommandLocked(const spIBinder token,std::optionalint32_t pid,std::string reason) { // 将command 保存到queue 中因为前面会直接返回 MIN所以线程会马山处理auto command [this, token, pid, reason std::move(reason)]() REQUIRES(mLock) {scoped_unlock unlock(mLock);mPolicy-notifyWindowUnresponsive(token, pid, reason);};postCommandLocked(std::move(command)); }// 通知到界面没有反应 notifyWindowUnresponsive /frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp // 前面将 NativeInputManager 保存到 了InputManager中 831 void NativeInputManager::notifyWindowUnresponsive(const spIBinder token, 832 std::optionalint32_t pid, 833 const std::string reason) { 834 #if DEBUG_INPUT_DISPATCHER_POLICY 835 ALOGD(notifyWindowUnresponsive); 836 #endif // 会打印对应的tracenotifyWindowUnresponsive 837 ATRACE_CALL(); 838 839 JNIEnv* env jniEnv(); 840 ScopedLocalFrame localFrame(env); 841 842 jobject tokenObj javaObjectForIBinder(env, token); 843 ScopedLocalRefjstring reasonObj(env, env-NewStringUTF(reason.c_str())); 844 // 调用java 层的方法 845 env-CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowUnresponsive, tokenObj, 846 pid.value_or(0), pid.has_value(), reasonObj.get()); 847 checkAndClearExceptionFromCallback(env, notifyWindowUnresponsive); 848 }/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java 2927 // Native callback 2928 SuppressWarnings(unused) 2929 private void notifyWindowUnresponsive(IBinder token, int pid, boolean isPidValid, 2930 String reason) { 2931 mWindowManagerCallbacks.notifyWindowUnresponsive(token, 2932 isPidValid ? OptionalInt.of(pid) : OptionalInt.empty(), reason); 2933 }/frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java 102 Override 103 public void notifyWindowUnresponsive(NonNull IBinder token, NonNull OptionalInt pid, 104 NonNull String reason) { 105 mService.mAnrController.notifyWindowUnresponsive(token, pid, reason); 106 }/frameworks/base/services/core/java/com/android/server/wm/AnrController.java 88 void notifyWindowUnresponsive(NonNull IBinder token, NonNull OptionalInt pid, 89 NonNull String reason) { 90 if (notifyWindowUnresponsive(token, reason)) { 91 return; 92 } 93 if (!pid.isPresent()) { 94 Slog.w(TAG_WM, Failed to notify that window token token was unresponsive.); 95 return; 96 } 97 notifyWindowUnresponsive(pid.getAsInt(), reason); 98 } 99 100 /** 101 * Notify a window identified by its input token was unresponsive. 102 * 103 * return true if the window was identified by the given input token and the request was 104 * handled, false otherwise. 105 */ 106 private boolean notifyWindowUnresponsive(NonNull IBinder inputToken, String reason) { 107 preDumpIfLockTooSlow(); 108 final int pid; 109 final boolean aboveSystem; 110 final ActivityRecord activity; 111 synchronized (mService.mGlobalLock) { 112 InputTarget target mService.getInputTargetFromToken(inputToken); 113 if (target null) { 114 return false; 115 } 116 WindowState windowState target.getWindowState(); 117 pid target.getPid(); 118 // Blame the activity if the input token belongs to the window. If the target is 119 // embedded, then we will blame the pid instead. 120 activity (windowState.mInputChannelToken inputToken) 121 ? windowState.mActivityRecord : null;// 会打印下列的log 122 Slog.i(TAG_WM, ANR in target . Reason: reason); 123 aboveSystem isWindowAboveSystem(windowState); 124 dumpAnrStateLocked(activity, windowState, reason); 125 } // ActivityRecord 不为空 126 if (activity ! null) { 127 activity.inputDispatchingTimedOut(reason, pid); 128 } else { 129 mService.mAmInternal.inputDispatchingTimedOut(pid, aboveSystem, reason); 130 } 131 return true; 132 }/frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java 6649 public boolean inputDispatchingTimedOut(String reason, int windowPid) { 6650 ActivityRecord anrActivity; 6651 WindowProcessController anrApp; 6652 boolean blameActivityProcess; 6653 synchronized (mAtmService.mGlobalLock) { 6654 anrActivity getWaitingHistoryRecordLocked(); 6655 anrApp app; 6656 blameActivityProcess hasProcess() 6657 (app.getPid() windowPid || windowPid INVALID_PID); 6658 } 6659 6660 if (blameActivityProcess) { 6661 return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner, 6662 anrActivity.shortComponentName, anrActivity.info.applicationInfo, 6663 shortComponentName, app, false, reason);/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 17647 boolean inputDispatchingTimedOut(ProcessRecord proc, String activityShortComponentName, 17648 ApplicationInfo aInfo, String parentShortComponentName, 17649 WindowProcessController parentProcess, boolean aboveSystem, String reason) { 17650 if (checkCallingPermission(FILTER_EVENTS) ! PackageManager.PERMISSION_GRANTED) { 17651 throw new SecurityException(Requires permission FILTER_EVENTS); 17652 } 17653 17654 final String annotation; 17655 if (reason null) { 17656 annotation Input dispatching timed out; // 这里增加 Input dispatching timed out 17657 } else { 17658 annotation Input dispatching timed out ( reason ); 17659 } 17660 17661 if (proc ! null) { 17662 synchronized (this) { 17663 if (proc.isDebugging()) { 17664 return false; 17665 } 17666 17667 if (proc.getActiveInstrumentation() ! null) { 17668 Bundle info new Bundle(); 17669 info.putString(shortMsg, keyDispatchingTimedOut); 17670 info.putString(longMsg, annotation); 17671 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 17672 return true; 17673 } 17674 }// 这里去弹框 17675 mAnrHelper.appNotResponding(proc, activityShortComponentName, aInfo, 17676 parentShortComponentName, parentProcess, aboveSystem, annotation); 17677 } 17678 17679 return true; 17680 }
http://www.hkea.cn/news/14418241/

相关文章:

  • 简单门户网站模板展厅设计概念方案
  • 网站备案 接电话wordpress编辑器 代码
  • 郑州七彩网站建设公司 评论塔城建设局网站
  • 给自己的爱人做网站网站建设和优化的营销话术
  • 莘县网站建设费用临海建设局网站
  • 株洲网络问政平台seo与网站建设的关联
  • 重庆塔吊证查询网站个人网站命名技巧
  • 如何安装织梦做的网站海口网站seo
  • 广州网站快速制作seo学徒是做什么
  • 阜宁网站制作哪家好鄠邑区建设和住房保障局网站
  • 网站建设的关键点中国建筑建设通的网站
  • 地方网站有何作用建设银行交易明细查询网站
  • 想要做一个网站 该怎么做cc插件 wordpress
  • 常州网站建设段新浩网站用html模拟图片
  • 用腾讯云做网站泰钢材企业网站源码
  • 没经验怎么开广告公司营销网站seo推广费用
  • 网站链接用处如何将网站添加到域名
  • 网站后台 用什么编写泉州企业建站系统
  • 甘肃做网站哪家专业电商公司经营范围
  • 微信网站建设 知乎lol小米和谁做的视频网站
  • 网站升级改版方案上海展览设计制作公司
  • xampp做网站可以吗智慧团建网站什么时候维护好
  • 怎么做游戏和网站漏洞wordpress 5图片相对路径
  • 深圳营销型网站建设公司免费海报制作网站
  • 珠海网站建设报价哪些企业需要网站建设
  • 企业网站建设word全国建设工程造价管理系统
  • 官网网站页面设计网站开发技术方案与实施
  • 网站开发需要英语营销型网站建设的优缺点
  • 网站建设与什么专业有关android手机网站开发
  • 美区能和国区家庭共享吗sem和seo哪个工作好