簡介
xCrash是愛奇藝開源的在android平台上面捕獲異常的開源庫。xCrash能為安卓 APP提供捕獲Java崩潰異常,native崩潰異常和ANR異常。
xCrash 能在 App 程序崩潰或 ANR 時,在你指定的目錄中生成一個 tombstone 檔案(格式與安卓系統的 tombstone 檔案類似)。
xCrash項目位址:
github:https://github.com/iqiyi/xCrash
gitee:https://gitee.com/caikelun/xCrash
xCrash源碼結構
通過git擷取xCrash源碼,可以獲知xcrash分為兩個module,兩個module分為是xcrash_lib,xcrash_sample。xcrash_lib是核心庫,xcrash_sample是提供的測試工程。
xcrash_lib工程結構如下:
下面對結構進行簡單的介紹:
ActivityMonitor:對app應用的activity通過list進行管理的工具類。
AnrHandler:anr異常捕獲處理器。
DefaultLogger:xcrash庫預設的日志輸出接口,預設為通過android.util.Log輸出日志。
Errno:xcrash常見的錯誤碼。
FileManager:異常日志管理器,負責建立異常日志檔案和清除過期的異常日志檔案。
ICrashCallback:異常回調接口。
ILibLoader:so庫加載回調接口。
ILogger:xcrash日志輸出接口,DefaultLogger是其實作類。
JavaCrashHandler:java異常處理器。
NativeHandler:native異常處理器
TombstoneManager和TombstoneParser:異常日志分析器
Util:工具類,提供java異常的輸出的基本資訊,判斷終端是否是root狀态,擷取記憶體資訊等等。
Version:xcrash的版本資訊。
XCrash:xcrash提供捕獲異常的配置和初始化的功能。
Java異常捕獲
xCrash捕獲Java異常的處理器類為JavaCrashHandler。JavaCrashHandler是UncaughtExceptionHandler的子類。UncaughtExceptionHandler是java系統提供用來處理未捕獲全局異常。
JavaCrashHandler
JavaCrashHandler是單例模式。
class JavaCrashHandler implements UncaughtExceptionHandler{
private static final JavaCrashHandler instance = new JavaCrashHandler();
private JavaCrashHandler() {
}
static JavaCrashHandler getInstance() {
return instance;
}
}
JavaCrashHandler初始化接口
JavaCrashHandler提供initialize接口,用于JavaCrashHandler初始化。JavaCrashHandler初始化的主要功能有:
- 儲存APP應用資訊。包括程序ID,程序名,應用版本。
- Java異常輸出配置,包括輸出日志路徑,是否抛出異常,配置輸出内容。
void initialize(int pid, String processName, String appId, String appVersion, String logDir, boolean rethrow,
int logcatSystemLines, int logcatEventsLines, int logcatMainLines,
boolean dumpFds, boolean dumpAllThreads, int dumpAllThreadsCountMax, String[] dumpAllThreadsWhiteList,
ICrashCallback callback){
}
JavaCrashHandler異常處理接口
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
if (defaultHandler != null) {
// xcrash不處理異常,采用預設的異常處理機制
Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
}
try {
// 處理Java異常
handleException(thread, throwable);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler handleException failed", e);
}
if (this.rethrow) {
// java預設異常處理,抛出異常
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, throwable);
}
} else {
// 關閉程序
ActivityMonitor.getInstance().finishAllActivities();
Process.killProcess(this.pid);
System.exit(10);
}
}
從源碼可知,處理的核心接口為handleException。handleException的源碼如下
private void handleException(Thread thread, Throwable throwable){
...
// 1. 通知native,anr異常處理器,java異常發生,其他異常處理器停止工作
NativeHandler.getInstance().notifyJavaCrashed();
AnrHandler.getInstance().notifyJavaCrashed();
// 2. 建立異常日志檔案
File logFile = null;
try {
// 異常日志檔案的命名規則
String logPath = String.format(Locale.US, "%s/%s_%020d_%s__%s%s", logDir, Util.logPrefix, startTime.getTime() * 1000, appVersion, processName, Util.javaLogSuffix);
logFile = FileManager.getInstance().createLogFile(logPath);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler createLogFile failed", e);
}
// 擷取java 異常輸出
String emergency = null;
try {
// 應用基本資訊,和java異常堆棧
emergency = getEmergency(crashTime, thread, throwable);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler getEmergency failed", e);
}
// 3.異常日志寫入檔案
if (logFile != null){
// 3.1 寫入emergency,java異常資訊
// 3.2 logcat 寫入異常檔案中 logcat -b main; logcat -b event; logcat -b system
// 3.3 輸出APP應用程序的檔案描述符資訊
// 3.4 輸出記憶體資訊
// 3.5 輸出其他線程資訊
}
}
Java異常整體比較簡單,可以通過源碼進行直覺的分析。後續會新增native異常和anr異常的分析。