<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                本章我們沒有對SystemServer做更進一步的分析,不過做為拓展內容,這里想介紹一下Watchdog。Watch Dog的中文意思是“看門狗”。我依稀記得,其最初存在的意義是因為早期嵌入式設備上的程序經常“跑飛”(比如說電磁干擾等),所以專門有個硬件看門狗,每隔一段時間,看門狗就去檢查一下某個參數是不是被設置了,如果發現該參數沒有被設置,則判斷為系統出錯,然后就會強制重啟。 軟件層面上Android對SystemServer對參數是否被設置也很謹慎,專門為它增加了一條看門狗,可它看的是哪個門呢?對了,就是看幾個重要Service的門,一旦發現Service出了問題,就會殺掉system_server,這樣就使zygote隨其一起自殺,最后導致重啟Java世界。 我們先把SystemServe使用Watchdog的調用流程總結一下,然后以這個為切入點來分析Watchdog。SS和Watchdog的交互流程可以總結為以下三個步驟: - Watchdog. getInstance().init() - Watchdog.getInstance().start() - Watchdog. getInstance().addMonitor() 這三個步驟都非常簡單。先看第一步: 1. 創建和初始化Watchdog getInstance用于創建Watchdog,一起來看看,代碼如下所示: **Watchdog.java** ~~~ public static Watchdog getInstance() { if(sWatchdog == null) { sWatchdog= new Watchdog(); //使用了單例模式。 } returnsWatchdog; } public class Watchdog extends Thread //Watchdog從線程類派生,所以它會在單獨的一個線程中執行 private Watchdog() { super("watchdog"); //構造一個Handler,Handler的詳細分析見第5章,讀者可以簡單地把它看做是消息處理的地方。 //它在handleMessage函數中處理消息 mHandler = new HeartbeatHandler(); //GlobalPssCollected和內存信息有關。 mGlobalPssCollected= new GlobalPssCollected(); } ~~~ 這條看門狗誕生后,再來看看init函數,代碼如下所示: **Watchdog.java** ~~~ public void init(Context context, BatteryServicebattery, 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() { booleanwaitedHalf = false; while(true) {//外層while循環 mCompleted= false; //false表明各個服務的檢查還沒完成。 /* mHandler的消息處理是在另外一個線程上,這里將給那個線程的消息隊列發條消息 請求Watchdog檢查Service是否工作正常。 */ mHandler.sendEmptyMessage(MONITOR); synchronized (this) { long timeout = TIME_TO_WAIT; long start = SystemClock.uptimeMillis(); //注意這個小while循環的條件,mForceKillSystem為true也會導致退出循環 while (timeout > 0 && !mForceKillSystem) { try { wait(timeout); //等待檢查的結果 } catch(InterruptedException e) { } timeout = TIME_TO_WAIT -(SystemClock.uptimeMillis() - start); } //mCompleted為true,表示service一切正常 if (mCompleted &&!mForceKillSystem) { waitedHalf = false; continue; } //如果mCompleted不為true,看門狗會比較盡責,再檢查一次 if (!waitedHalf) { ...... waitedHalf = true; continue;//再檢查一次 } } //已經檢查過兩次了,還是有問題,這回是真有問題了。所以SS需要把自己干掉。 if (!Debug.isDebuggerConnected()) { Process.killProcess(Process.myPid()); System.exit(10); //干掉自己 } ...... waitedHalf = false; } } ~~~ OK,這個run函數還是比較簡單的,就是: · 隔一段時間給另外一個線程發送一條MONITOR消息,那個線程將檢查各個Service的健康情況。而看門狗會等待檢查結果,如果第二次還沒有返回結果,那么它會殺掉SS。 好吧,來看看檢查線程究竟是怎么檢查Service的。 3. 列隊檢查 這么多Service,哪些是看門狗比較關注的呢?一共有三個Service是需要交給Watchdog檢查的: - ActivityManagerService - PowerManagerService - WindowManagerService 要想支持看門狗的檢查,就需要這些Service實現monitor接口,然后Watchdog就會調用它們的monitor函數進行檢查了。檢查的地方是在HeartbeatHandler類的handleMessage中,代碼如下所示: **Watchdog.java::HeartbeatHandler** ~~~ final class HeartbeatHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { ...... case MONITOR: { ...... long now =SystemClock.uptimeMillis(); final int size =mMonitors.size(); //檢查各個服務,并設置當前檢查的對象為mCurrentMonitor for (int i = 0 ; i <size ; i++) { mCurrentMonitor =mMonitors.get(i); mCurrentMonitor.monitor();//檢查這個對象 } //如果沒問題,則設置mCompleted為真。 synchronized (Watchdog.this){ mCompleted = true; mCurrentMonitor = null; } } break; } } } ~~~ 那么,Service的健康是怎么判斷的呢?我們以PowerManagerService為例,先看看它是怎么把自己交給看門狗檢查的。 **PowerManagerService.java** ~~~ PowerManagerService() { ...... //在構造函數中把自己加入Watchdog的檢查隊列 Watchdog.getInstance().addMonitor(this); } ~~~ 而Watchdog調用各個monitor函數到底檢查了些什么呢?再看看它實現的monitor函數吧。 **PowerManagerService.java** ~~~ public void monitor() { //monitor原來檢查的就是這些Service是不是發生死鎖了! synchronized (mLocks) { } } ~~~ 原來,Watchdog最怕系統服務死鎖了,對于這種情況也只能采取殺系統的辦法了。 >[info]**說明**:這種情況,我只碰到過一次,原因是有一個函數占著鎖,但長時間沒有返回。沒返回的原因是這個函數需要和硬件交互,而硬件又沒有及時返回。 關于Watchdog,我們就介紹到這里。另外,它還能檢查內存的使用情況,這一部分內容讀者可以自行研究。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看