上篇我们介绍了WatchDog启动流程,本节主要介绍下WatchDog中比较重要的内部接口Monitor和几个核心函数
addThread是WatchDog的一个函数
public void addThread(Handler thread) {
// DEFAULT_TIMEOUT默认为30秒
addThread(thread, DEFAULT_TIMEOUT);
}
public void addThread(Handler thread, long timeoutMillis) {
synchronized (mLock) {
final String name = thread.getLooper().getThread().getName();
mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
}
}
可以看到,该函数通过Handler和DEFAULT_TIMEOUT参数构造了HandlerChecker对象,并且加入了mHandlerCheckers 列表中。在Android WatchDog启动流程中我们已经讲过,在WatchDog的构造函数中,mHandlerCheckers已经添加了一些元素。
每一个HandlerChecker对象实际上就是一个线程的信息,HandlerChecker会定期的去检测当前线程是否被阻塞,这部分内容我们后面章节详解,这里先知道个大概即可。
addThread是WatchDog的一个函数
public void addMonitor(Monitor monitor) {
synchronized (mLock) {
mMonitorChecker.addMonitorLocked(monitor);
}
}
mMonitorChecker是一个HandlerChecker对象,由Android WatchDog启动流程文中可知,mMonitorChecker在WatchDog构造函数中进行了初始化。看下addMonitorLocked的实现:
void addMonitorLocked(Monitor monitor) {
// We don't want to update mMonitors when the Handler is in the middle of checking
// all monitors. We will update mMonitors on the next schedule if it is safe
mMonitorQueue.add(monitor);
}
讲monitor添加到了mMonitorQueue中,这个还没见过,我们看下其定义:
private final ArrayList<Monitor> mMonitorQueue = new ArrayList<Monitor>();
可以看到,mMonitorQueue是一个元素为Monitor的列表。
到这里,我们总结一下:
addThread函数用参数Handler构造了一个HandlerChecker对象,然后添加到了mHandlerCheckers列表中。
addMonitor函数将当前对象添加到了mMonitorChecker对象的内部变量mMonitorQueue列表中。
Monitor是WatchDog的内部接口,如下:
public interface Monitor {
void monitor();
}
可以看到该接口只有一个monitor()方法,凡是想要被WatchDog监测的对象必须实现这个接口,并通过addMonitor函数进行注册,比如WMS:
public class WindowManagerService extends IWindowManager.Stub
// 实现了Watchdog.Monitor接口
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
......
// 实现了monitor函数
// Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
@Override
public void monitor() {
synchronized (mGlobalLock) { }
}
......
public void onInitReady() {
initPolicy();
// 通过addMonitor将自己加入到WatchDog监测中
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
createWatermark();
showEmulatorDisplayOverlayIfNeeded();
}
小结: