如何自定義一個全域性異常捕獲器-SpiderMan
阿新 • • 發佈:2019-01-09
一圖勝前言
上圖中,我們模擬了NullPointerException的發生,系統捕獲了該異常,並用一個介面展示了出來。
如何實現
想要實現全域性異常的捕獲我們需要了解Thead
中的一個內部介面UncaughtExceptionHandler
,該介面在JDK1.5中被新增。
所有我們需要自定義一個類去實現該介面,並且設定給Thread
的DefaultUncaughtExceptionHandler
。
//虛擬碼
public class SpiderMan implements Thread.UncaughtExceptionHandler {
private SpiderMan () {
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable ex) {
}
}
複製程式碼
UncaughtExceptionHandler
會捕獲程式碼中沒有捕獲的異常,然後回撥給uncaughtException
方法。
高階操作
解析Throwable
private CrashModel parseCrash(Throwable ex) {
CrashModel model = new CrashModel();
try {
model.setEx(ex);
model.setTime(new Date().getTime());
if (ex.getCause() != null) {
ex = ex.getCause();
}
model.setExceptionMsg(ex.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
pw.flush();
String exceptionType = ex.getClass().getName();
if (ex.getStackTrace() != null && ex.getStackTrace().length > 0) {
StackTraceElement element = ex.getStackTrace()[0];
model.setLineNumber(element.getLineNumber());
model.setClassName(element.getClassName());
model.setFileName(element.getFileName());
model.setMethodName(element.getMethodName());
model.setExceptionType(exceptionType);
}
model.setFullException(sw.toString());
} catch (Exception e) {
return model;
}
return model;
}
複製程式碼
如上程式碼所示,我們可以從Throwable類中解析出很多有用的資訊,包括崩潰發生的類
,所在行數
,exception的型別
...
跳轉新的介面顯示Crash資訊
Intent intent = new Intent(mContext, CrashActivity.class);
intent.putExtra(CrashActivity.CRASH_MODEL, model);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
複製程式碼
在對Throwable解析完成後,我們就可以跳轉到一個新的Activity並展示Crash的相關資訊,這裡Context
是Application的Context,所有必須使用Intent.FLAG_ACTIVITY_NEW_TASK
才能成功跳轉。
分享Crash資訊
分享文字
把Throwable解析成有用的字串,呼叫系統的分享方法
private void shareText(String text) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "崩潰資訊:");
intent.putExtra(Intent.EXTRA_TEXT, text);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(intent, "分享到"));
}
複製程式碼
分享長圖
分享圖片要涉及東西就多啦,比如ScrollView的截圖,如何儲存到Sd卡,6.0需要動態許可權檢測,7.0還要相容fileprovider,具體看原始碼吧,哈哈哈哈!