AndroidWatchDog

1Android中的WatchDog

本文主要介绍androidframework层中的watchdog,它属于一种软件Watchdog实现。

WatchDog主要作用:

1).接收系统内部reboot请求,重启系统。

2).监护SystemServer进程,防止系统死锁。

2WatchDog启动

WatchDog是在SystemServer进程中被初始化和启动的。在SystemServerStart时,各种Android服务被注册和启动,其中也包括了WatchDog的初始化和启动。代码如下:

Slog.i(TAG,"InitWatchdog");

Watchdog.getInstance().init(context,battery,power,alarm,ActivityManagerService.self());

//Watchdog本身继承Thread,是一个线程类。此为WatchDog初始化。

.SystemServerRun函数的后半段,将检查系统是否已经准备好运行第三方代码,并通过SystemReady接口通知系统已经就绪。在ActivityManagerServiceSystemReady接口的CallBack函数中实现WatchDog的启动

Watchdog.getInstance().start();

//以上代码位于/Frameworks/base/services/java/com/android/server/SystemServer.java中。

3WatchDog内部架构及主要接口介绍

WatchDog内部主要部件和接口函数为:HeartbeatHandlerRebootReceiverRebootRequestReceivercheckRebootrebootSystemMonitoraddMonitor

HeartbeatHandler此为WatchDog的核心,负责对各个监护对象进行监护。

RebootReceiver负责接收由AlarManagerService发出的PendingIntent,并进行系统重启。该PendingIntentWatchDog内部创建,"com.android.service.Watchdog.REBOOT"

RebootRequestReceiver负责接收系统内部发出的重启Intent消息,并进行系统重启。

checkReboot判断是否需要重启系统。

rebootSystem调用PowerManagerreboot接口重启系统。

Monitor每个被监护对象必须要实现的接口,由WatchDog在运行中调用,以实现监护功能。

addMonitor将实现了monitor接口的监护对象注册到WatchDog服务中。

4WatchDog工作流程

4.1WatchDog监护对象

要实现调用WatchDog对其进行监护,则必须实现

1)WatchDog.Monitor接口,这个接口中只有一个monitor函数。

2)将该对象注册到WatchDog服务中,在初始化中作如下处理:Watchdog.getInstance().addMonitor(this);

AndroidWatchDog运行在SystemServer进程,对其进行监护,而其中监护的服务为以下三个:

ActivityManagerServiceWindowManagerServicePowerMangerService

ActivityManagerService为例:

/**Inthismethodwetrytoacquireourlocktomakesurethatwehavenotdeadlocked*/

publicvoidmonitor(){

synchronized(this){}

}

该接口函数其实内部并不做任何处理,只是去锁一下对象,然后返回。如果对象没有死锁,则过程会很顺利,若对象死锁,则该函数就会挂在这里。

其它两个Service对象实现的monitor接口函数与Activity类似,也同样是去获取一下锁而已。

4.2WatchDog监护流程

WatchDog启动之后,开始跑run函数。该函数内部为一个无限循环。

publicvoidrun(){

booleanwaitedHalf=false;

while(true){

mCompleted=false;

mHandler.sendEmptyMessage(MONITOR);

...

while(timeout>0&&!mForceKillSystem){

try{

wait(timeout);

}catch(InterruptedExceptione){

}

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

//TIME_TO_WAIT的默认时间为30s。此为第一次等待时间,WatchDog判断对象是否死锁的最长处理时间为1Min

}

...

}

}

一开始就会发送一个MONITORMessage,由HeartbeatHandler负责接收并处理。同时会等待30秒,等待HeartbeatHandler的处理结果。然后才会进行下一步动作。

HeartbeatHandler中将会作如下处理:

publicvoidhandleMessage(Messagemsg){

switch(msg.what){

caseMONITOR:{

...

finalintsize=mMonitors.size();

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

mCurrentMonitor=mMonitors.get(i);

mCurrentMonitor.monitor();

}//依次去调用监护对象的monitor接口,实现对其的监护。具体操作内容见4.1

synchronized(Watchdog.this){

mCompleted=true;

mCurrentMonitor=null;

}//如果监护的对象都正常,则会很快运行到这里,并对mCompleted赋值为true,表示对象正常返回。mCompleted值初始为false

同时在run函数中:if(mCompleted&&!mForceKillSystem){

//Themonitorshavereturned.

waitedHalf=false;

continue;

}//如果所有对象在30s内能够返回,则会得到mCompleted=true;则本次监护就结束,返回继续下一轮监护。

如果在30s内,monitor对象未能返回,mCompleted值即为false,则会运行到该语句:

if(!waitedHalf){

//We'vewaitedhalfthedeadlock-detectioninterval.Pullastack

//traceandwaitanotherhalf.

ArrayList<Integer>pids=newArrayList<Integer>();

pids.add(Process.myPid());

ActivityManagerService.dumpStackTraces(true,pids,null,null);

waitedHalf=true;

continue;

}//会调用ActivityManagerService.java中的dumpStackTraces接口函数。

在该接口中,主要会对SystemServer进程的stackTrace的信息dump出来,以及检测目前运行AppCPU使用率。由SystemServer进程发送一个SIGNAL_QUIT的进程信号:

publicstaticFiledumpStackTraces(...,...){

...

Process.sendSignal(firstPids.get(i),Process.SIGNAL_QUIT);

...

//NextmeasureCPUusage.

if(processStats!=null){

processStats.init();

System.gc();//运行garbageCollector.

processStats.update();

...

//We'lltakethestackcrawlsofjustthetopappsusingCPU.

finalintN=processStats.countWorkingStats();

intnumProcs=0;

for(inti=0;i<N&&numProcs<5;i++){

ProcessStats.Statsstats=processStats.getWorkingStats(i);

if(lastPids.indexOfKey(stats.pid)>=0){

numProcs++;

try{

Process.sendSignal(firstPids.get(i),Process.SIGNAL_QUIT);

}

...

}

该动作发生在第一次等待的30s时间内,monitor对象未返回,由于在调用完ActivityManagerService.javadumpStackTraces接口函数后,将waitedHalf赋值为true。并返回继续下一轮监护。若紧接着的下一轮监护,在30smonitor对象依旧未及时返回,此时

if(mCompleted&&!mForceKillSystem){

...

}

if(!waitedHalf){

...

}//此时这两个语句都不会运行,则会直接运行到下面部分。这表示系统的监护对象有死锁现象发生,SystemServer进程需要kill并重启。

//Pass!waitedHalfsothatjustincasewesomehowwindupherewithouthaving

//dumpedthehalfwaystacks,weproperlyre-initializethetracefile.

finalFilestack=ActivityManagerService.dumpStackTraces(

!waitedHalf,pids,null,null);

//Givesomeextratimetomakesurethestacktracesgetwritten.

//Thesystem'sbeenhangingforaminute,anothersecondortwowon'thurtmuch.

SystemClock.sleep(2000);

...

//Onlykilltheprocessifthedebuggerisnotattached.

if(!Debug.isDebuggerConnected()){

Process.killProcess(Process.myPid());

System.exit(10);//在剩下的30s内,做一些收尾工作,如重新初始化tracefile。最后直接将SystemServer进程kill,并且退出系统。Init进程会重新启动SystemServer进程,让其回到可用状态。

更多相关文章

  1. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第五
  2. Android 无线接口层RIL
  3. android对html支持接口总结
  4. Android 匿名共享内存Java接口分析
  5. Android rest接口
  6. android 常用api 接口签名验证
  7. Android高手进阶教程(十七)之---Android中Intent传递对象的两种
  8. Android中将资源文件转为Bitmap对象
  9. 面向UDP的Android——PC双向通信(三):在Android客户端和PC服务器端

随机推荐

  1. Matplotlib 中等高线图(contour)的绘制
  2. 努力不一定能成,不努力一定不成
  3. 【Android】实现登录、注册、数据库操作(
  4. 万字长文详解Python正则表达式及re模块
  5. 浅谈生活中的短网址和短ID
  6. Markdown中输入数学公式及LaTex常用数学
  7. 笔试练习题(十)
  8. 偷学Python第二十九|time模块和calendar模
  9. “三本”如何高效自学前端四个月逆袭
  10. Python办公自动化|自动更新不对称表格