【Android】处理线程中未捕获的异常
需求
项目出现异常问题,获取崩溃信息
实现
定义一个类,实现【Thread.UncaughtExceptionHandler】方法
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static CrashHandler sInstance = new CrashHandler();
private Context mContext;
private CrashHandler() {
}
public static CrashHandler getInstance() {
return sInstance;
}
public void init(Context context) {
//将当前应用异常处理器改为默认的
Thread.setDefaultUncaughtExceptionHandler(this);
mContext = context.getApplicationContext();
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
//导入异常信息到SD卡中
try {
saveExceptionToSDCard(ex);
} catch (IOException e) {
e.printStackTrace();
}
ex.printStackTrace();
//activity任务栈里,只要还存在activity就会重启,需要将他们都finish掉才真正不会重启,
//有个链接可以看一下 https://www.jianshu.com/p/eb34c5df30e5
if(mContext instanceof MyApplication) ((MyApplication)mContext).removeActivityTasks();
Process.killProcess(Process.myPid());//直接杀死进程,防止自动重启
System.exit(0);
}
/**
* 将异常信息写入SD卡
*/
private void saveExceptionToSDCard(Throwable e) throws IOException {
//如果SD卡不存在或无法使用,则无法将异常信息写入SD卡
//得到当前年月日时分秒
long current = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(new Date(current));
//在定义的Crash文件夹下创建文件
File file = new File(FilePathUtil.getFullPath(DManager.ROOT +File.separator+DManager.LOGGER+File.separator+"error") + "crash_" + time + ".txt");
try{
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
//写入时间
pw.println(time);
//写入手机信息
dumpPhoneInfo(pw);
pw.println();//换行
e.printStackTrace(pw);
pw.close();//关闭输入流
} catch (Exception e1) {
Log.e(TAG,"dump crash info failed");
}
}
/**
* 获取手机各项信息
*/
private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {
//得到包管理器
PackageManager pm = mContext.getPackageManager();
//得到包对象
PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES);
//写入APP版本号
pw.print("App Version: ");
pw.print(pi.versionName);
pw.print("_");
pw.println(pi.versionCode);
//写入 Android 版本号
pw.print("OS Version: ");
pw.print(Build.VERSION.RELEASE);
pw.print("_");
pw.println(Build.VERSION.SDK_INT);
//手机制造商
pw.print("Vendor: ");
pw.println(Build.MANUFACTURER);
//手机型号
pw.print("Model: ");
pw.println(Build.MODEL);
//CPU架构
pw.print("CPU ABI: ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
pw.println(Build.SUPPORTED_ABIS);
}else {
pw.println(Build.CPU_ABI);
}
}
}
在这里,我们把异常信息写入到了本地我们指定的文件下面,或者我们也可以将异常信息上传到服务器等方便分析错误异常信息。
在应用程序启动时调用 init 方法,将 CrashHandler 设置为默认的未捕获异常处理器。
当线程中出现未捕获的异常时,uncaughtException 方法会被调用
我们可以在MyApplication类里面调用这个
CrashHandler.getInstance().init(this);