不知道你有沒有遇過,就是有時系統開機異常,會直接進入到一個機器人的error界面。我這邊就遇到,在OTA升級後,開機後會自動重啓,且進入到機器人error界面。經查找,是因爲有一個進程在系統開機的時候,不斷重啓,觸發了RescueParty機制,今天在這帶你們稍微瞭解下這個機制。java
目前市場上的消費者包括小白用戶,當他們的手機出現無限循環啓動的異常時,用戶沒有辦法修復異常只能經過設備商售後處理。android
Google在Android 8.0加入該新功能,稱之爲rescue party救援程序。shell
主要監控系統核心程序出現循環崩潰的時候,會啓動該程序,根據不一樣的救援級別作出一系列操做,看是否可恢復設備,最嚴重的時候則是經過進入recovery而後提供用戶清空用戶數據恢復出廠設置解決。api
frameworks\base\services\core\java\com\android\server\RescueParty.java
複製代碼
private static final int LEVEL_NONE = 0;
private static final intLEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS = 1; //主要針對非系統進程的屬性設置進行重置
private static final intLEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES = 2;//針對非系統進程屬性,來自系統默認的屬性重置,其餘刪除
private static final intLEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS = 3;//全部進程系統默認的屬性重置,其餘刪除
private static final intLEVEL_FACTORY_RESET = 4; //嘗試恢復出廠設置
複製代碼
(1)system_server 在 5 分鐘內重啓 5 次以上調整一次級別。
(2)永久性系統應用在 30 秒內崩潰 5 次以上調整一次級別。
複製代碼
(1)PROP_ENABLE_RESCUE屬性值爲false,而且PROP_DISABLE_RESCUE爲true
(2)eng版本下
(3)手機鏈接usb模式
複製代碼
在AppErrors.java的crashApplicationInner方法中加上了RescueParty監控,具體代碼以下:app
void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
int callingPid, int callingUid) {
...
// If a persistent app is stuck in a crash loop, the device isn't very
// usable, so we want to consider sending out a rescue party.
if (r != null && r.persistent) {
RescueParty.notePersistentAppCrash(mContext, r.uid);
}
AppErrorResult result = new AppErrorResult();
TaskRecord task;
...
}
複製代碼
這裏調用了 RescueParty的notePersistentAppCrash方法,並傳入了Context和進程uid.如今咱們進入方法內部看看:ide
/**
* Take note of a persistent app crash. If we notice too many of these
* events happening in rapid succession, we'll send out a rescue party.
*/
public static void notePersistentAppCrash(Context context, int uid) {
if (isDisabled()) return;
Threshold t = sApps.get(uid);
if (t == null) {
t = new AppThreshold(uid);
sApps.put(uid, t);
}
if (t.incrementAndTest()) {
t.reset();
incrementRescueLevel(t.uid);
executeRescueLevel(context);
}
}
複製代碼
當設備具備有效的 USB 數據鏈接時,系統會中止全部救援事件,由於這是一個較強的信號,表示有人正在調試設備。oop
要中止此類抑制行爲,請運行:ui
adb shell setprop persist.sys.enable_rescue 1
複製代碼
查看源碼,可發現,在判斷該機制是否生效的方法中,該屬性被放在最前面,即優先判斷該屬性。spa
在此處,您能夠觸發系統或界面崩潰循環。debug
要觸發低級 system_server 崩潰循環,請運行:
adb shell setprop debug.crash_system 1
複製代碼
要觸發中級 SystemUI 崩潰循環,請運行:
adb shell setprop debug.crash_sysui 1
複製代碼
這兩個崩潰循環都會啓動救援邏輯。全部的救援操做也都會記錄到存儲在 /data/system/uiderrors.txt 中的永久性的 PackageManager 日誌中,以供往後進行檢查和調試。 此外,「軟件包警告消息」部分下的每一個錯誤報告中也會包含這些永久性的日誌。