一、在嵌入式设备上的应用

Watch Dog的中文意思是“看门狗”,最初是应用子啊嵌入式设备上的,目的是为了防止程序跑飞,所以专门设置了一个硬件看门狗,每隔一段时间,看门狗就会去检查一下某个参数是不是被设置了,如果发现该参数设置出错,就会强制重启程序。

二、在Android上的应用

Android对SystemServer参数是否被设置时很谨慎的,所以专门为它增加了看门狗,可他到底看哪个门呢?就是看几个重要的Service门,如果Android一旦发现几个重要的Service门出问题,就会马上杀掉进程system_server,而这也会使zygote一起自杀,最后导致重启Java世界。

三、Android中的Watchdog分析

我们先把SystemServer使用Watchdog的调用流程总结一下,然后以为为切入点来分析Watchdog。system_server和Watchdog的交互流程可以总结为一下三个步骤:

a、Watchdog.getInstance().init();

b、Watchdog.getInstance().start();

c、Watchdog.getInstance().addMonitor();

这三个步骤都很简单。先看第一步。

getInstance用户创建Watchdog,代码如下:

【-->Watchdog.java】

public static Watchdog getInstance(){

if(sWatchdog == null){

sWatchdog = new Watchdog();//使用了单例模式

}

return sWatchdog;


public class Watchdog extends Thread{

//Watchdog从线程类派生,所以它会在一个单独的线程中执行

private Watchdog(){

mHandler = new HeartbeatHandler();

//GlobalPssCollected和内存信息有关

mGlobalPsCollected = new GlobalPssCollected();

}


public void init(Context context,BatteryService battery,PowerManagerService power,AlarmManagerService alarm,ActivityManagerService activity){

mResolver = context.getContentResolver();

mBattery = battery;

mPower = power;

mAlarm = alarm;

mActivity = activity;

.....

mBootTime = System.currentTimeMillis();//得到当前时间

......

}

到这里,看门狗就诞生了,下面就让他动起来。

2、让看门狗跑起来

SystemServer调用Watchdog的start函数,这将导致Watchdog的run在另外一个线程中被执行。代码如下:

【-->Watchdog.java】

public void run(){

boolean waitedHalf = false;

while(true){

mCompleted = false;//false表示各国服务的检查还未完成。

//mHandler的消息处理是在另外一个线程中,这里将给那个线程发消息,请求Watchdog检查Service是否正常工作。

mHandler.sendEmptyMessage(MONITOR);

synchronized(this){

long timeout = TIME_TO_MAIT;

long start = SystemClock.uptimeMillis();

//注意这个小while循环的条件,mForceKillSystem为true时也会导致推出循环。

while(timeout > 0 && !mForceKillSystem){

try{

wait(timeout);//等待检查的结果

}catch{

}

timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start);

}

//mCompleted为true,表示service一切正常

if(mCompleted && !mForceKillSystem){

waitedHalf = false;

continue;

}

//如果mCompleted不为true,看门狗会尽责的再检查一次。

if(!waitedHalf){

......

waitedHalf = true;

continue;//再检查一次

}

}

//已经检查两次了,如果再出现,这回真的有问题了,所以system_server需要将自己干掉。

if(!Debug.idDebuggerConncted()){

Process.killProcess(Process.myPid());

System.exit(10);//干掉自己

}

......

waiteHalf = false;

}

}


上面Run方法里的意思是:

隔一段时间给另外一个线程发送一条MONITOR消息,哪个线程将检查各个Service的健康情况。而看门狗会等待检查结果,如果第二次还没有返回结果,那么就会杀死进程systen_server。

下面我们看看线程是怎么检查Service的。

3、列队检查

这么多的Service,看门狗到底是检查哪个呢?答案是一共有三个Service需要交给Watchgod检查:

a、ActivityManagerService

b、PowerManagerService

c、WindowManagerService

要想支持看门狗的检查,就需要让这些Service实现monitor接口,然后Watchdog就会调用它们的monitor函数进行检查了。检查的地方时在HeartbeatHandler类的handleMessage中,代码如下:

【-->Watchdog.java::HeartbeatHandler】

final class HearbeatHandler extends Handler{

@Overode

public void handleMessage(Message msg){

switch(msg.what){

......

case MONITOR:{

......

logg now = SystemClock.uptimeMillis();

final int size = mMontitors.size();

//检查各个服务,并设置当前检查对象为mCurrentMonitor。

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

mCurrentMonitor = mMonitors.get(i);

mCurrentMonitor.monitor();//检查这个对象

}

//如果没问题,则设置mCurrentMonitor.monitor();//检查这个对象

synchronized(Watchdog.this){

mCompleted = true;

mCurrentMonitor = null;

}

}break;

}

}

}

那么Service的健康状况是怎么判读呢?我们以PowerManagerService为例,先看看它是怎么把自己交给看门狗检查的,代码入下:

【-->PowerManagerService.java】

PowerManagerService(){

......

//z在构造函数中把自己加入Watchdog的检查队列

Watchdog.getInstance().addMonitor(this);

}

而Watchdog调用各个monitor函数到底又检查了些什么呢?看看它的实现monitor函数吧!

【-->PowerManagerService.java】

public void monitor(){

//原来monitor检查的就是这些Service是否发生死锁了!

synchronized(mLocks){}

}

原来,Watchdog最怕系统服务死锁了,对于这种情况也只能采取杀死进程的办法了。












更多相关文章

  1. Android(安卓)中的线程形态 -- AsyncTask,HandlerThread,IntentSer
  2. android中的通信机制总结1:使用handler来进行通信
  3. android权限申请库解析
  4. android 模拟器调用系统照相机
  5. android 线程消息处理【之消息处理中再处理的个人学习小思考】
  6. Android使用后台线程提高用户体验
  7. Android的进程与线程(3)线程安全问题
  8. Android中线程和Handle
  9. 线程池与Android的日日夜夜

随机推荐

  1. 编译android 64位openssl库
  2. Android获取移动设备的IP地址
  3. 解决Conversion to Dalvik format failed
  4. android 开源自组织网络开源包
  5. 今天玩玩Android -==-- 了解一下
  6. 如何在Android单元测试中调试async-http
  7. Android小代码——设置全屏
  8. Android 获取电池电量
  9. 控件_AnalogClock
  10. Android中RadioGroup RadioButton CheckB