編輯:關於Android編程
本文基於Android4.4,
最近查了下watchdog打印錯誤log的問題。頭都大。。。也查看了下android framework 下watchdog的實現代碼,做個記錄以備後邊溫習,以及新入行後輩們能夠快速上手
以PowerManagerservice為例做簡單流程分析
Watchdog功能:
1. 監視reboot廣播
2. 監視加到check list 的service是否死鎖
功能介紹:
功能1非常簡單,就是注冊一個broadcastreceiver,收到關機的Action就去走關機或reboot流程
主要說下功能2
PowerManagerService.java:
先說一下構造函數:
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.getMainLooper()),
"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));
}
紅色部分很重要,添加UIThread,FgThread,IoThread,還有當前new Watchdog時候的主線程,其實就是System_server主線程
接下來說下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); //添加本對象到monitor列表裡
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構造函數裡
mMonitorChecker = newHandlerChecker(FgThread.getHandler(),
"foreground thread",DEFAULT_TIMEOUT);
public void addMonitor(Monitor monitor){
//mMonitors是一個數組list ArrayList
//添加powermanagerservice對象到此list
mMonitors.add(monitor);
}
接著說下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");
}
//把PowerManagerHandler 對象添加到mHandlerCheckers列表
mHandlerCheckers.add(newHandlerChecker(thread, name, timeoutMillis));
}
}
准備工作到此已經做完,接下來就是watchdog不停監視每個service是否死鎖
代碼主要在Watchdog.java
System_server會啟動watchdog會跑到run函數:
WatchDog運行在一個單獨的線程中,它的線程執行方法run()的代碼如下:
HandlerChecker hc =mHandlerCheckers.get(i);
hc.scheduleCheckLocked();
}
run()方法中有一個無限循環,每次循環中主要做三件事:
1.
publicvoidscheduleCheckLocked() {
}
HandlerChecker對象即要監控服務,也要監控某個線程。所以上面的代碼先判斷mMonitors的size是否為0。如果為0,說明這個HandlerChecker沒有監控服務,這時如果被監控線程的消息隊列處於空閒狀態(調用isIdling()檢查),則說明線程運行良好,把mCompleted設為true後就可以返回了。否則先把mCompleted設為false,然後記錄消息開始發送的時間到變量mStartTime中,最後調用postAtFrontOfQueue()方法給被監控的線程發送一個消息。此時在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();
}
這個消息的處理方法是HandlerChecker類的方法run(),代碼如下:
publicvoidrun() {
}
如果消息處理方法run()能夠被執行,說明受監控的線程本身沒有問題。但是還需要檢查被監控服務的狀態。檢查是通過調用服務中實現的monitor()方法來完成的。通常monitor()方法的實現是獲取服務中的鎖,如果不能得到,線程就會被掛起,這樣mCompleted的值就不能被置成true了。
mCompleted的值為true,表明HandlerChecker對象監控的線程或服務正常。否則就可能有問題。是否真有問題還要通過等待的時間是否超過規定時間來判斷。
moninor()方法的實現通常如下:
publicvoidmonitor() {
}
2.
3.
前面調用了方法evaluateCheckerCompletio
privateintevaluateCheckerCompletio
}
!waitedHalf, pids, null, null,NATIVE_STACKS_OF_INTEREST);
getCompletionStateLocked
publicintgetCompletionStateLocked
}
到此就已經分析完畢,如果對發送消息不明白可以看我博文裡handler,looper的那篇文章。中間網上找了些博文,借鑒。如果有什麼不足之處,請指正。。
幾個常用的方法:1.setTitle()設置對話框顯示的標題。2.setIcon()設置對話框的圖標,值得注意的是,如果沒有使用setTitle()方法,setIcon(
本文實例為大家分享了Android聯系人字母排序的具體代碼,供大家參考,具體內容如下實現思路:首先說下布局,整個是一個相對布局,最下面是一個listview,listvi
一.背景做視頻用到了就記錄下,從github(https://github.com/curtis2/SuperVideoPlayer 謝謝)上扒了一個項目的手勢調亮度和音
應用開發中需要獲取WebView當前頁面的標題,可能通過對WebChromeClient.onReceivedTitle()方法的重寫來實現 效果圖如下: 代碼如下: