Android 4.4 Watchdog机制

来源:互联网 发布:microsoftoutlook mac 编辑:程序博客网 时间:2024/05/08 11:55

Android 软watchdog机制主要功能集中在两个层面:

1),监听系统的reboot广播;

2),监听相关service是否死锁。


首先,从代码看,watchdog是由SystemServer.java启动:


这几行代码首先是初始化了watchdog,



添加UIThread,FgThread,IoThread,还有当前new Watchdog时候的主线程,其实就是System_server主线程。

添加至mHandlerCheckers这个MonitorList中,接下来看init接口:



这个接口里边将需要watchdog监听的几个service赋值过来,同时注册接收reboot的广播。

随后SystemServer通过Watchdog.getInstance().start();调用其run方法,开始循环侦听功能。

run()方法中有一个无限循环,每次循环中主要做三件事:

1. 调用scheduleCheckLocked()方法给所有受监控的线程发送消息。scheduleCheckLocked()方法的代码如下

publicvoidscheduleCheckLocked() {

 if(mMonitors.size() == 0 &&mHandler.getLooper().isIdling()) {

 mCompleted= true;

 return;

 }

 if(!mCompleted) {

 return;

 }

 mCompleted= false;

 mCurrentMonitor= null;

 mStartTime= SystemClock.uptimeMillis();

 mHandler.postAtFrontOfQueue(this);//给监视的线程发送消息

}

 

HandlerChecker对象即要监控服务,也要监控某个线程。所以上面的代码先判断mMonitors的size是否为0。如果为0,说明这个HandlerChecker没有监控服务,这时如果被监控线程的消息队列处于空闲状态(调用isIdling()检查),则说明线程运行良好,把mCompleted设为true后就可以返回了。否则先把mCompleted设为false,然后记录消息开始发送的时间到变量mStartTime中,最后调用postAtFrontOfQueue()方法给被监控的线程发送一个消息。此时在Handler.java的

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if(mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

private static void handleCallback(Message message) {

message.callback.run();

}

这个消息的处理方法是HandlerChecker类的方法run(),代码如下:

public void run() {

 finalint size = mMonitors.size();

 for(int i = 0 ; i < size ; i++) {

 synchronized(Watchdog.this) {

 mCurrentMonitor= mMonitors.get(i);

 }

 mCurrentMonitor.monitor();

 }

 synchronized(Watchdog.this) {

 mCompleted= true;

 mCurrentMonitor= null;

 }

}

如果消息处理方法run()能够被执行,说明受监控的线程本身没有问题。但是还需要检查被监控服务的状态。检查是通过调用服务中实现的monitor()方法来完成的。通常monitor()方法的实现是获取服务中的锁,如果不能得到,线程就会被挂起,这样mCompleted的值就不能被置成true了。

mCompleted的值为true,表明HandlerChecker对象监控的线程或服务正常。否则就可能有问题。是否真有问题还要通过等待的时间是否超过规定时间来判断。

moninor()方法的实现通常如下:

public void monitor() {

 synchronized(mLock) {

 }

}

2. 给受监控的线程发送完消息后,调用wait()方法让WatchDog线程睡眠一段时间。

3. 逐个检查是否有线程或服务出问题了,一旦发现问题,马上杀死进程。

前面调用了方法evaluateCheckerCompletionLocked()来检查线程或服务是否有问题。evaluateCheckerCompletionLocked()方法的代码如下:

privateintevaluateCheckerCompletionLocked() {

 intstate = COMPLETED;

 for(int i=0; i < mHandlerCheckers.size(); i++) {

 HandlerCheckerhc =mHandlerCheckers.get(i);

 state= Math.max(state,hc.getCompletionStateLocked());

 }

 returnstate;

}

getCompletionStateLocked()函数根据等待时间来确认返回HandlerChecker对象的状态,代码如下:

public int getCompletionStateLocked() {

 if(mCompleted) {

 returnCOMPLETED;

 }else {

 longlatency = SystemClock.uptimeMillis() -mStartTime;

 if(latency < mWaitMax/2) {

 returnWAITING;

 }else if (latency < mWaitMax) {

 returnWAITED_HALF;

 }

 }

 returnOVERDUE;

}

本文只对流程做了相对简单的分析,抛开监听reboot广播不说,在我看来,监听线程就是定时分别尝试获取一次添加到watchdog monitorcheckerList中的service的monitor()接口(尝试获取一次service内部的锁),如果成功获取并释放,则说明service未出现死锁的状况,则一段时间后继续该操作;如若不然,即获取service内相关的锁失败,则说明有service可能处于死锁状态,从而Watchdog线程杀死SystemServer进程。SystemServer监控重要service,重要service hang则SystemServer死,SystemServer死则Zygote监控到,Zygote也死并且杀死整个Java世界,Zygote死则init监控到,init重新启动Zygote,之后SystemServer、service又进入重生过程。





















0 0