(点击
上方公众号
,可快速关注)
来源:伯乐在线专栏作者 - gityuan
链接:http://android.jobbole.com/84881/
点击 → 了解如何加入专栏作者
一、概述
Android系统中,有硬件WatchDog用于定时检测关键硬件是否正常工作,类似地,在framework层有一个软件WatchDog用于定期检测关键系统服务是否发生死锁事件。WatchDog功能主要是分析系统核心服务和重要线程是否处于Blocked状态。
-
监视reboot广播;
-
监视mMonitors关键系统服务是否死锁。
二、启动流程
2.1 startOtherServices
[-> SystemServer.java]
private
void
startOtherServices
()
{
...
//创建watchdog【见小节2.2】
final
Watchdog
watchdog
=
Watchdog
.
getInstance
();
//注册reboot广播【见小节2.3】
watchdog
.
init
(
context
,
mActivityManagerService
);
...
mSystemServiceManager
.
startBootPhase
(
SystemService
.
PHASE_LOCK_SETTINGS_READY
);
...
mActivityManagerService
.
systemReady
(
new
Runnable
()
{
@Override
public
void
run
()
{
mSystemServiceManager
.
startBootPhase
(
SystemService
.
PHASE_ACTIVITY_MANAGER_READY
);
...
// watchdog启动【见小节3.1】
Watchdog
.
getInstance
().
start
();
mSystemServiceManager
.
startBootPhase
(
SystemService
.
PHASE_THIRD_PARTY_APPS_CAN_START
);
}
}
}
2.2 getInstance
[-> Watchdog.java]
public
static
Watchdog getInstance
()
{
if
(
sWatchdog
==
null
)
{
//单例模式,创建实例对象【见小节2.2.1 】
sWatchdog
=
new
Watchdog
();
}
return
sWatchdog
;
}
2.2.1 创建Watchdog
[-> Watchdog.java]
public
class
Watchdog
extends
Thread
{
...
private
Watchdog
()
{
super
(
"watchdog"
);
//【见小节2.2.2 】
mMonitorChecker
=
new
HandlerChecker
(
FgThread
.
getHandler
(),
"foreground thread"
,
DEFAULT_TIMEOUT
);
mHandlerCheckers
.
add
(
mMonitorChecker
);
mHandlerCheckers
.
add
(
new
HandlerChecker
(
new
Handler
(
Looper
.
getMainLooper
()),
"main thread"
,
DEFAULT_TIMEOUT
));
mHandlerCheckers
.
add
(
new
HandlerChecker
(
UiThread
.
getHandler
(),
"ui thread"
,
DEFAULT_TIMEOUT
));
mHandlerCheckers
.
add
(
new
HandlerChecker
(
IoThread
.
getHandler
(),
"i/o thread"
,
DEFAULT_TIMEOUT
));
mHandlerCheckers
.
add
(
new
HandlerChecker
(
DisplayThread
.
getHandler
(),
"display thread"
,
DEFAULT_TIMEOUT
));
//【见小节2.2.3】
addMonitor
(
new
BinderThreadMonitor
());
}
}
Watchdog继承于Thread,创建的线程名为”watchdog”。mHandlerCheckers是记录着所有的HandlerChecker对象的列表。
Watchdog监控的线程有:
线程名
|
对应handler
|
含义
|
main thread
|
new Handler(MainLooper)
|
当前主线程
|
android.fg
|
FgThread.getHandler
|
前台线程
|
android.ui
|
UiThread.getHandler
|
UI线程
|
android.io
|
IoThread.getHandler
|
I/O线程
|
android.display
|
DisplayThread.getHandler
|
Display线程
|
DEFAULT_TIMEOUT默认为60s,调试时才为10s方便找出潜在的ANR问题。
2.2.2 HandlerChecker
[-> Watchdog.java]
public
final
class
HandlerChecker
implements
Runnable
{
...
HandlerChecker
(
Handler
handler
,
String
name
,
long
waitMaxMillis
)
{
mHandler
=
handler
;
mName
=
name
;
mWaitMax
=
waitMaxMillis
;
mCompleted
=
true
;
}
}
mMonitors记录所有Watchdog目前正在监控的服务。
2.2.3 监控Binder线程
在小节【2.2.1】创建Watchdog时,通过addMonitor(new BinderThreadMonitor())来监控Binder线程, 这里拆分两步骤:
-
addMonitor
-
new BinderThreadMonitor
2.2.3.1 addMonitor
public
class
Watchdog
extends
Thread
{
public
void
addMonitor
(
Monitor
monitor
)
{
synchronized
(
this
)
{
if
(
isAlive
())
{
throw
new
RuntimeException
(
"Monitors can't be added once the Watchdog is running"
);
}
//此处mMonitorChecker数据类型为HandlerChecker
mMonitorChecker
.
addMonitor
(
monitor
);
}
}
public
final
class
HandlerChecker
implements
Runnable
{
private
final
ArrayList
mMonitors
=
new
ArrayList
();
public
void
addMonitor
(
Monitor
monitor
)
{
//将上面的BinderThreadMonitor添加到mMonitors队列
mMonitors
.
add
(
monitor
);
}
...
}
}
将monitor添加到HandlerChecker的成员变量mMonitors列表中。
2.2.3.2 BinderThreadMonitor
private
static
final
class
BinderThreadMonitor
implements
Watchdog
.
Monitor
{
public
void
monitor
()
{
Binder
.
blockUntilThreadAvailable
();
}
}
blockUntilThreadAvailable最终调用的是IPCThreadState,等待有空闲的binder线程
void
IPCThreadState
::
blockUntilThreadAvailable
()
{
pthread_mutex_lock
(
&
mProcess
->
mThreadCountLock
);
while
(
mProcess
->
mExecutingThreadsCount
>=
mProcess
->
mMaxThreads
)
{
//等待正在执行的binder线程小于进程最大binder线程上限(16个)
pthread_cond_wait
(
&
mProcess
->
mThreadCountDecrement
,
&
mProcess
->
mThreadCountLock
);
}
pthread_mutex_unlock
(
&
mProcess
->
mThreadCountLock
);
}
可见addMonitor(new BinderThreadMonitor())是将Binder线程添加到android.fg线程的handler(mMonitorChecker)来检查是否工作正常。
2.2.4 Monitor
public
class
Watchdog
extends
Thread
{
public
interface
Monitor
{
void
monitor
();
}
}
能够被Watchdog监控的系统服务都实现了Watchdog.Monitor接口。 实现该接口类:
2.3 init
[-> Watchdog.java]
public
void
init
(
Context
context
,
ActivityManagerService
activity
)
{
mResolver
=
context
.
getContentResolver
();
mActivity
=
activity
;
//注册reboot广播接收者【见小节2.3.1】
context
.
registerReceiver
(
new
RebootRequestReceiver
(),
new
IntentFilter
(
Intent
.
ACTION_REBOOT
),
android
.
Manifest
.
permission
.
REBOOT
,
null
);
}
2.3.1 RebootRequestReceiver
[-> Watchdog.java]
final
class
RebootRequestReceiver
extends
BroadcastReceiver
{
@Override
public
void
onReceive
(
Context
c
,
Intent
intent
)
{
if
(
intent
.
getIntExtra
(
"nowait"
,
0
)
!=
0
)
{
//【见小节2.3.2】
rebootSystem
(
"Received ACTION_REBOOT broadcast"
);
return
;
}
Slog
.
w
(
TAG
,
"Unsupported ACTION_REBOOT broadcast: "
+
intent
);
}
}
2.3.2 rebootSystem
[-> Watchdog.java]
void
rebootSystem
(
String
reason
)
{
Slog
.
i
(
TAG
,
"Rebooting system because: "
+
reason
);
IPowerManager
pms
=
(
IPowerManager
)
ServiceManager
.
getService
(
Context
.
POWER_SERVICE
);
try
{
//通过PowerManager执行reboot操作
pms
.
reboot
(
false
,
reason
,
false
);
}
catch