public class UnCatchExceptionHandler implements Thread.UncaughtExceptionHandler {
private Context mContext;
private Thread.UncaughtExceptionHandler mHandler;
// 保存手机信息和异常信息
private Map<String, String> mMessage = new HashMap<>();
private UnCatchExceptionHandler(){}
private static UnCatchExceptionHandler sUnCatchExceptionHandler = new UnCatchExceptionHandler();
public static UnCatchExceptionHandler getmExceptionHandler(){
return sUnCatchExceptionHandler;
}
public void init(Context mContext){
this.mContext = mContext.getApplicationContext();
mHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
if (!handlerException(e)){
if (mHandler != null){
mHandler.uncaughtException(t, e);
}
}else{
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
Process.killProcess(Process.myPid());
}
//退出程序
AppManager.getAppManager().AppExit(mContext);
}
}
/**
* 是否人为捕获异常
*
* @param e Throwable
* @return true:已处理 false:未处理
*/
private boolean handlerException(Throwable e){
if (e == null){
return false;
}
new Thread(){
@Override
public void run() {
Looper.prepare();
ToastUtil.Toast("捕获到异常");
Looper.loop();
}
}.start();
collectErrorMessages();
saveErrorMessages(e);
return false;
}
/**
* 1.收集错误信息
*/
private void collectErrorMessages() {
PackageManager pm = mContext.getPackageManager();
try {
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = TextUtils.isEmpty(pi.versionName) ? "null" : pi.versionName;
String versionCode = "" + pi.versionCode;
mMessage.put("versionName", versionName);
mMessage.put("versionCode", versionCode);
}
// 通过反射拿到错误信息
Field[] fields = Build.class.getFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
field.setAccessible(true);
try {
mMessage.put(field.getName(), field.get(null).toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
/**
* 2.保存错误信息
*
* @param e Throwable
*/
private void saveErrorMessages(Throwable e) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : mMessage.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key).append("=").append(value).append("\n");
}
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
Throwable cause = e.getCause();
// 循环取出Cause
while (cause != null) {
cause.printStackTrace(pw);
cause = e.getCause();
}
pw.close();
String result = writer.toString();
sb.append(result);
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(new Date());
String fileName = "crash-" + time + "-" + System.currentTimeMillis() + ".log";
// 有无SD卡
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory().getPath() + "crash/";
File dir = new File(path);
if (!dir.exists()) dir.mkdirs();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
} catch (Exception e1) {
e1.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
}
捕获类写完后在App里面引用:
//捕获全局异常
UnCatchExceptionHandler.getmExceptionHandler().init(this);