近来看了一些异常补抓相关资料,正好补一下相应的操作,发现爱奇艺的一个Xcrash的异常补抓框架
文章分为三部分,分别是Java奔溃,卡顿补抓,以及Native崩溃。
可以看一下基本架构的全貌
这一节是Java崩溃的说明
基本初始化是在自定义的Application的attachBaseContext来进行,在这里设置主线程异常崩溃补抓的UncaughtExceptionHandler
void initialize(int pid, String processName, String appId, String appVersion, String logDir, boolean rethrow,
int logcatSystemLines, int logcatEventsLines, int logcatMainLines,
boolean dumpFds, boolean dumpNetworkInfo, boolean dumpAllThreads, int dumpAllThreadsCountMax, String[] dumpAllThreadsWhiteList,
ICrashCallback callback) {
this.pid = pid;
this.processName = (TextUtils.isEmpty(processName) ? "unknown" : processName);
this.appId = appId;
this.appVersion = appVersion;
this.rethrow = rethrow;
this.logDir = logDir;
this.logcatSystemLines = logcatSystemLines;
this.logcatEventsLines = logcatEventsLines;
this.logcatMainLines = logcatMainLines;
this.dumpFds = dumpFds;
this.dumpNetworkInfo = dumpNetworkInfo;
this.dumpAllThreads = dumpAllThreads;
this.dumpAllThreadsCountMax = dumpAllThreadsCountMax;
this.dumpAllThreadsWhiteList = dumpAllThreadsWhiteList;
this.callback = callback;
//保存默认的异常补抓
this.defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
try {
//设置新的异常补抓
Thread.setDefaultUncaughtExceptionHandler(this);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler setDefaultUncaughtExceptionHandler failed", e);
}
}
继承接口uncaughtException
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
if (defaultHandler != null) {
Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
}
try {
//回调自己的逻辑
handleException(thread, throwable);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler handleException failed", e);
}
if (this.rethrow) {
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, throwable);
}
} else {
//栈记录清空
ActivityMonitor.getInstance().finishAllActivities();
//强杀进程
Process.killProcess(this.pid);
System.exit(10);
}
}
处理补抓到的java异常
```
private void handleException(Thread thread, Throwable throwable) {
Date crashTime = new Date();
//notify the java crash 通知native和anr监听为处理为java崩溃
NativeHandler.getInstance().notifyJavaCrashed();
AnrHandler.getInstance().notifyJavaCrashed();
//create log file 日志地址
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);
}
//get emergency 日志头信息
String emergency = null;
try {
emergency = getEmergency(crashTime, thread, throwable);
} catch (Exception e) {
XCrash.getLogger().e(Util.TAG, "JavaCrashHandler getEmergency failed", e);
}
//write info to log file 编写日志文件
if (logFile != null) {
//使用文本处理
RandomAccessFile raf = null;