Adnroid Watchdog implementation

Source: Internet
Author: User

Adnroid Watchdog implementation

This article is based on Android4.4,

 

I recently checked the error log printed by watchdog. The headers are all big... I also checked the implementation code of watchdog under the android framework, made a record for later review, and was able to get started quickly by new generations.

 

Take PowerManagerservice as an example for simple Process Analysis

 

Watchdog function:

1. Monitor reboot Broadcast

2. monitor whether the service added to the check list is deadlocked

 

Function introduction:

Function 1 is very simple, that is, registering a broadcastreceiver, receives the shutdown Action and goes through the shutdown or reboot process.

Function 2

PowerManagerService. java:

Let's talk about the constructor:

Private Watchdog (){

Super ("watchdog ");

// Initialize handler checkers for each common thread we want tocheck. Note

// That we are not currently checking the background thread, since itcan

// Potentially hold longer running operations with no guarantees aboutthe timeliness

// Of operations there.

 

// The shared foreground thread is the main checker. It is where we

// Will also dispatch monitor checks and do other work.

MMonitorChecker = newHandlerChecker (FgThread. getHandler (),

"Foreground thread", DEFAULT_TIMEOUT );

MHandlerCheckers. add (mMonitorChecker );

// Add checker for main thread. We only do a quick check since there

// Can be UI running on the thread.

MHandlerCheckers. add (new HandlerChecker (newHandler (Looper. getmainloker ()),

"Main thread", DEFAULT_TIMEOUT ));

// Add checker for shared UI thread.

MHandlerCheckers. add (newHandlerChecker (UiThread. getHandler (),

"Ui thread", DEFAULT_TIMEOUT ));

// And also check IO thread.

MHandlerCheckers. add (newHandlerChecker (IoThread. getHandler (),

"I/o thread", DEFAULT_TIMEOUT ));

}

The red part is very important. You can add UIThread, FgThread, IoThread, and the main thread of the new Watchdog, which is actually the main thread of System_server.

 

Next let's talk about init:

Public void init (Context context, LightsService ls,

ActivityManagerService am, BatteryService bs, IBatteryStats bss,

IAppOpsService appOps, DisplayManagerService dm ){

......

MHandlerThread = new HandlerThread (TAG );

MHandlerThread. start ();

MHandler = new PowerManagerHandler (mHandlerThread. getLooper ());

 

Watchdog. getInstance (). addMonitor (this); // Add this object to the monitor list

Watchdog. getInstance (). addThread (mHandler, mHandlerThread. getName ());

......

}

Public void addMonitor (Monitor monitor ){

Synchronized (this ){

If (isAlive ()){

Throw newRuntimeException ("Monitors can't be added once the Watchdog isrunning ");

}

MMonitorChecker. addMonitor (monitor );//

}

}

 

 

Watchdog Constructor

MMonitorChecker = newHandlerChecker (FgThread. getHandler (),

"Foreground thread", DEFAULT_TIMEOUT );

 

Public void addMonitor (Monitor monitor ){

// MMonitors is an array list ArrayList MMonitors = newArrayList ();

// Add the powermanagerservice object to this list

MMonitors. add (monitor );

}

 

Next let's talk about Watchdog. getInstance (). addThread (mHandler, mHandlerThread. getName ());

 

Public void addThread (Handler thread, String name ){

AddThread (thread, name, DEFAULT_TIMEOUT );

}

 

Public void addThread (Handler thread, String name, long timeoutMillis ){

Synchronized (this ){

If (isAlive ()){

Throw newRuntimeException ("Threads can't be added once the Watchdog isrunning ");

}

 

// Add the PowerManagerHandler object to the mHandlerCheckers list

MHandlerCheckers. add (newHandlerChecker (thread, name, timeoutMillis ));

}

}

 

The preparation has been completed. Next, watchdog keeps monitoring whether each service is deadlocked.

The code is mainly used in Watchdog. java

 

System_server starts watchdog and runs to the run function:

WatchDog runs in a separate thread. Its thread execution method run () code is as follows:

Public void run (){

BooleanwaitedHalf = false;

While (true ){

FinalArrayListblockedCheckers;

FinalStringsubject;

FinalbooleanallowRestart;

Synchronized (this ){

Longtimeout = CHECK_INTERVAL;

// Send messages to the monitored thread

For (inti = 0; I

HandlerChecker hc = mHandlerCheckers. get (I );

Hc. scheduleCheckLocked ();

}

// Sleep for a period of time

Longstart = SystemClock. uptimeMillis ();

While (timeout> 0 ){

Try {

Wait (timeout );

} Catch (InterruptedException e ){

Log. wtf (TAG, e );

}

Timeout = CHECK_INTERVAL-(SystemClock. uptimeMillis ()-start );

}

// Check whether a thread or service has a problem

FinalintwaitState = evaluateCheckerCompletioNLocked ();

If (waitState = COMPLETED ){

WaitedHalf = false;

Continue;

} Elseif (waitState = WAITING ){

Continue;

} Elseif (waitState = WAITED_HALF ){

If (! WaitedHalf ){

ArrayListpids = new ArrayList ();

Pids. add (Process. myPid ());

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

NATIVE_STACKS_OF_INTEREST );

WaitedHalf = true;

}

Continue;

}

......

{

// Kill SystemServer

Process. killProcess (Process. myPid ());

System. exit (10 );

}

WaitedHalf = false;

}

}

The run () method has an infinite loop. Each loop mainly performs three tasks:

1. Call the scheduleCheckLocked () method to send messages to all monitored threads. The code for the scheduleCheckLocked () method is as follows:

PublicvoidscheduleCheckLocked (){

If (mMonitors. size () = 0 & mHandler. getloors (). isIdling ()){

MCompleted = true;

Return;

}

If (! MCompleted ){

Return;

}

MCompleted = false;

MCurrentMonitor = null;

MStartTime = SystemClock. uptimeMillis ();

MHandler. postAtFrontOfQueue (this); // send a message to the monitored thread

}

 

The HandlerChecker object monitors the service and a thread. Therefore, the code above first checks whether the size of mMonitors is 0. If the value is 0, the HandlerChecker does not monitor the service. If the message queue of the monitored thread is idle (isIdling () Check is called), the thread runs well, set mCompleted to true and then return. Otherwise, set mCompleted to false, record the message start time to the variable mStartTime, and call the postAtFrontOfQueue () method to send a message to the monitored thread. In Handler. java

Public voiddispatchMessage (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 ();

}

The message processing method is the HandlerChecker class method run (). The Code is as follows:

Publicvoidrun (){

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;

}

}

If the message processing method run () can be executed, it indicates that the monitored thread itself is normal. However, you also need to check the status of the monitored service. The check is completed by calling the monitor () method implemented in the service. Generally, the implementation of the monitor () method is to obtain the lock in the service. If it cannot be obtained, the thread will be suspended, so that the value of mCompleted cannot be set to true.

The value of mCompleted is true, indicating that the thread or service monitored by the HandlerChecker object is normal. Otherwise, problems may occur. Whether a problem exists depends on whether the waiting time exceeds the specified time.

The moninor () method is usually implemented as follows:

Publicvoidmonitor (){

Synchronized (mLock ){

}

}

2. After sending a message to the monitored thread, call the wait () method to sleep the WatchDog thread for a period of time.

3. Check whether there are any threads or service problems one by one. If any problem is found, kill the process immediately.

The evaluateCheckerCompletio method is called earlier.NLocked () to check whether there is a problem with the thread or service. EvaluateCheckerCompletioThe code for the nLocked () method is as follows:

PrivateintevaluateCheckerCompletioNLocked (){

Intstate = COMPLETED;

For (int I = 0; I

HandlerCheckerhc = mHandlerCheckers. get (I );

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

}

Returnstate;

}

! WaitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST );

GetCompletionStateLocked() The function returns the status of the HandlerChecker object based on the waiting time. The Code is as follows:

PublicintgetCompletionStateLocked(){

If (mCompleted ){

ReturnCOMPLETED;

} Else {

Longlatency = SystemClock. uptimeMillis ()-mStartTime;

If (latency <mWaitMax/2 ){

ReturnWAITING;

} Else if (latency <mWaitMax ){

ReturnWAITED_HALF;

}

}

ReturnOVERDUE;

}

Now, the analysis has been completed. If you do not understand the message sending, you can read the handler and logoff article in my blog. I found some blog posts on the intermediate Internet for reference. If you have any shortcomings, please correct them ..

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.