Android WatchDog(4) - watchdog线程(Android 12)

598 阅读1分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

WatchDog启动流程中我们讲到,WatchDog启动时会启动名为watchdog的mThread线程,本节我们分析该线程的run函数,也作为WatchDog系列的最后一篇。

long timeout = CHECK_INTERVAL;//30s
// Make sure we (re)spin the checkers that have become idle within
// this wait-and-check interval
for (int i=0; i<mHandlerCheckers.size(); i++) {
      HandlerChecker hc = mHandlerCheckers.get(i);
      // 这里会在新的线程执行,所以循环很快会出去
      hc.scheduleCheckLocked();
 }

这部分会遍历mHandlerCheckers元素的scheduleCheckLocked函数,Handler Checker详解中已经对该函数做过详细分析,这里不再赘述。

                long start = SystemClock.uptimeMillis();
                while (timeout > 0) {
                    if (Debug.isDebuggerConnected()) {
                        debuggerWasConnected = 2;
                    }
                    try {
                        mLock.wait(timeout);
                        // Note: mHandlerCheckers and mMonitorChecker may have changed after waiting
                    } catch (InterruptedException e) {
                        Log.wtf(TAG, e);
                    }
                    if (Debug.isDebuggerConnected()) {
                        debuggerWasConnected = 2;
                    }
                    timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
                }

这一段比较简单,其实就是wait 30秒。

                final int waitState = evaluateCheckerCompletionLocked();
                if (waitState == COMPLETED) {
                    // The monitors have returned; reset
                    waitedHalf = false;
                    continue;
                } else if (waitState == WAITING) {
                    // still waiting but within their configured intervals; back off and recheck
                    continue;
                } else if (waitState == WAITED_HALF) {
                    if (!waitedHalf) {
                        Slog.i(TAG, "WAITED_HALF");
                        waitedHalf = true;
                        // We've waited half, but we'd need to do the stack trace dump w/o the lock.
                        pids = new ArrayList<>(mInterestingJavaPids);
                        doWaitedHalfDump = true;
                    } else {
                        continue;
                    }
                } else {
                    // something is overdue!
                    blockedCheckers = getBlockedCheckersLocked();
                    subject = describeCheckersLocked(blockedCheckers);
                    allowRestart = mAllowRestart;
                    pids = new ArrayList<>(mInterestingJavaPids);
                }

30秒后判断是否有HandlerChecker处于overdue状态,如果有的话将收集相关日志,此部分较为简单不再详述。

至此,WatchDog内容分析完毕。接下来我们综合本系列文章,对WatchDog进行总结。

  1. Android系统启动时,由SystemServer启动WatchDog线程作初始化操作,并且启动线程。
  2. 需要被WatchDog监测的类需要实现WatchDog的Monitor接口,并实现monitor函数,在monitor函数中进行对象锁的调用,用来配合WatchDog HandlerChecker 判断是否有死锁的发生。
  3. HandlerChecker会遍历所有被监测的对象,并且每隔30秒回调一下所有被监测对象的monitor函数,如果有一个对象的monitor函数没有被回调,则认为该对象上发生了死锁,此时会开始搜集相关日志信息进行输出和保存。