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