<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之旅 廣告
                1. binderDied函數分析 **ActvityManagerService.java::AppDeathRecipientbinderDied** ~~~ public void binderDied() { //注意,該函數也是通過Binder線程調用的,所以此處要加鎖 synchronized(ActivityManagerService.this) { appDiedLocked(mApp, mPid, mAppThread); } } ~~~ 最終的處理函數是appDiedLocked,其中所傳遞的3個參數保存了對應死亡進程的信息。來看appDiedLocked的代碼:: **ActvityManagerService.java::appDiedLocked** ~~~ final void appDiedLocked(ProcessRecord app, intpid, IApplicationThread thread) { ...... if(app.pid == pid && app.thread != null && app.thread.asBinder() == thread.asBinder()) { //當內存低到水位線時,LMK模塊也會殺死進程。對AMS來說,需要區分進程死亡是LMK導致的 //還是其他原因導致的。App instrumentationClass一般都為空,故此處doLowMem為true booleandoLowMem = app.instrumentationClass == null; //①下面這個函數非常重要 handleAppDiedLocked(app, false, true); if(doLowMem) { boolean haveBg = false; //如果系統中還存在oom_adj大于HIDDEN_APP_MIN_ADJ的進程,就表明不是LMK模塊因 //內存不夠而導致進程死亡的 for(int i=mLruProcesses.size()-1; i>=0; i--) { ProcessRecord rec = mLruProcesses.get(i); if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ){ haveBg = true;//還有后臺進程,故可確定系統內存尚未吃緊 break; } }//for循環結束 //如果沒有后臺進程,表明系統內存已吃緊 if(!haveBg) { long now = SystemClock.uptimeMillis(); for(int i=mLruProcesses.size()-1; i>=0; i--) { .....//將這些進程按一定規則加到mProcessesToGc中,盡量保證 //heavy/important/visible/foreground的進程位于mProcessesToGc數組 //的前端 }//for循環結束 /* 發送GC_BACKGROUND_PROCESSES_MSG消息給mHandler,該消息的處理過程就是: 調用應用進程的scheduleLowMemory或processInBackground函數。其中, scheduleLowMemory將觸發onLowMemory回調被調用,而processInBackground將 觸發應用進程進行一次垃圾回收 讀者可自行閱讀該消息的處理函數performAppGcsIfAppropriateLocked */ scheduleAppGcsLocked(); }// if(!haveBg)判斷結束 }//if(doLowMem)判斷結束 } ~~~ 以上代碼中有一個關鍵函數handleAppDiedLocked,下面來看它的處理過程。 2. handleAppDiedLocked函數分析 **ActivityManagerService.java::handleAppDiedLocked** ~~~ private final voidhandleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart) { //①在本例中,傳入的參數為restarting=false, allowRestart=true cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); if(!restarting) { mLruProcesses.remove(app); } ......//下面還有一部分代碼處理和Activity相關的收尾工作,讀者可自行閱讀 } ~~~ 重點看上邊代碼中的cleanUpApplicationRecordLocked函數,該函數的主要功能就是處理Service、ContentProvider及BroadcastReceiver相關的收尾工作。先來看Service方面的工作。 (1) cleanUpApplicationRecordLocked之處理Service **ActivityManagerService.java::cleanUpApplicationRecordLocked** ~~~ privatefinal void cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index) { if (index>= 0) mLruProcesses.remove(index); mProcessesToGc.remove(app); //如果該Crash進程有對應打開的對話框,則關閉它們,這些對話框包括crash、anr和wait等 if(app.crashDialog != null) { app.crashDialog.dismiss(); app.crashDialog = null; } ......//處理anrDialog、waitDialog //清理app的一些參數 app.crashing = false; app.notResponding = false; ...... //處理該進程中所駐留的Service或它和別的進程中的Service建立的Connection關系 //該函數是AMS Service處理流程中很重要的一環,讀者要仔細閱讀 killServicesLocked(app,allowRestart); ~~~ cleanUpApplicationRecordLocked函數首先處理幾個對話框(dialog),然后調用killServicesLocked函數做相關處理。作為Service流程的一部分,讀者需要深入研究。 (2) cleanUpApplicationRecordLocked之處理ContentProvider 再來看cleanUpApplicationRecordLocked下一階段的工作,主要和ContentProvider有關。 **ActivityManagerService.java::cleanUpApplicationRecordLocked** ~~~ booleanrestart = false; int NL = mLaunchingProviders.size(); if(!app.pubProviders.isEmpty()) { //得到該進程中發布的ContentProvider信息 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator(); while(it.hasNext()) { ContentProviderRecord cpr = it.next(); cpr.provider = null; cpr.proc = null; int i = 0; if(!app.bad && allowRestart) { for (; i<NL; i++) { /* 如果有客戶端進程在等待這個已經死亡的ContentProvider,則系統會 嘗試重新啟動它,即設置restart變量為true */ if (mLaunchingProviders.get(i) == cpr) { restart = true; break; } }//for循環結束 } else i = NL; if(i >= NL) { /* 如果沒有客戶端進程等待這個ContentProvider,則調用下面這個函數處理它,我們 在卷I的第10章曾提過一個問題,即ContentProvider進程被殺死 后,系統該如何處理那些使用了該ContentProvider的客戶端進程。例如,Music和 MediaProvider之間有交互,如果殺死了MediaProvider,Music會怎樣呢? 答案是系統會殺死Music,證據就在removeDyingProviderLocked函數 中,讀者可自行閱讀其內部處理流程 */ removeDyingProviderLocked(app, cpr); NL = mLaunchingProviders.size(); } }// while(it.hasNext())循環結束 app.pubProviders.clear(); } //下面這個函數的功能是檢查本進程中的ContentProvider是否存在于 // mLaunchingProviders中,如果存在,則表明有客戶端在等待,故需考慮是否重啟本進程或者 //殺死客戶端(當死亡進程變成bad process的時,需要殺死客戶端) if(checkAppInLaunchingProvidersLocked(app, false)) restart = true; ...... ~~~ 從以上的描述中可知,ContentProvider所在進程和其客戶端進程實際上有著非常緊密而隱晦(之所以說其隱晦,是因為SDK中沒有任何說明)的關系。在目前軟件開發追求模塊間盡量保持松耦合關系的大趨勢下,Android中的ContentProvider和其客戶端這種緊耦合的設計思路似乎不夠明智。不過,這種設計是否是不得已而為之呢?讀者不妨探討一下,如果有更合適的解決方案,期待能一起分享。 (3) cleanUpApplicationRecordLocked之處理BroadcastReceiver **ActivityManagerService.java::cleanUpApplicationRecordLocked** ~~~ skipCurrentReceiverLocked(app); //從AMS中去除接收者 if(app.receivers.size() > 0) { Iterator<ReceiverList> it = app.receivers.iterator(); while(it.hasNext()) { removeReceiverLocked(it.next()); } app.receivers.clear(); } if(mBackupTarget != null && app.pid == mBackupTarget.app.pid) { //處理Backup信息 } mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid,null).sendToTarget(); //注意該變量名為restarting,前面設置為restart. if(restarting) return; if(!app.persistent) { mProcessNames.remove(app.processName, app.info.uid); if(mHeavyWeightProcess == app) { ......//處理HeavyWeightProcess } } elseif (!app.removed) { if(mPersistentStartingProcesses.indexOf(app) < 0) { mPersistentStartingProcesses.add(app); restart = true; } } mProcessesOnHold.remove(app); if (app== mHomeProcess) mHomeProcess = null; if(restart) {//如果需要重啟,則調用startProcessLocked處理它 mProcessNames.put(app.processName, app.info.uid, app); startProcessLocked(app, "restart", app.processName); } elseif (app.pid > 0 && app.pid != MY_PID) { synchronized (mPidsSelfLocked) { mPidsSelfLocked.remove(app.pid); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); } app.setPid(0); } } ~~~ 在這段代碼中,除了處理BrodcastReceiver方面的工作外,還包括其他方面的收尾工作。最后,如果要重啟該應用,則需調用startProcessLocked函數進行處理。這部分代碼不再詳述,讀者可自行閱讀。
                  <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>

                              哎呀哎呀视频在线观看