Android全局异常处理
前言:
在开辟中我们会遇到步伐瓦解闪退的问题,但是不是每次瓦解闪退都能抓到报错的异常信息,为了方便步伐开辟调试,定位分析异常发生的原因,我们希望步伐在瓦解闪退的时候可以或许把异常信息纪录下来,方便我们后期分析。这时候我们可以用全局异常处理来实现异常信息纪录的功能。
代码实现
- 创建异常处理类CrashHandler,当步伐发生Uncaught异常的时候,由该类来继承步伐,并纪录错误日志。
- public class CrashHandler implements UncaughtExceptionHandler { private static final String TAG = "MyCrash"; // 系统默认的UncaughtException处理类 private UncaughtExceptionHandler mDefaultHandler; @SuppressLint("StaticFieldLeak") private static CrashHandler instance = new CrashHandler(); private Context mContext; // 用于格式化日期,作为日志文件名的一部分 private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); /** * 包管只有一个CrashHandler实例 */ private CrashHandler() { } /** * 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { return instance; } /** * 初始化 */ public void init(Context context) { mContext = context.getApplicationContext(); // 获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); // 设置该CrashHandler为步伐的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); } /** * 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { // 如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); } else { SystemClock.sleep(3000); // 退出步伐 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } /** * 自界说错误处理,收集错误信息 发送错误报告等利用均在此完成. */ private boolean handleException(Throwable ex) { if (ex == null) return false; try { // 使用Toast来显示异常信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "很歉仄,步伐出现异常,即将返回.", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); // 生存日志文件 saveCrashInfoFile(ex); SystemClock.sleep(3000); } catch (Exception e) { e.printStackTrace(); } return true; } /** * 生存错误信息到文件中 */ private void saveCrashInfoFile(Throwable ex) throws Exception { StringBuilder sb = new StringBuilder(); try { SimpleDateFormat sDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); String date = sDateFormat.format(new Date()); sb.append("\r\n").append(date).append("\n"); Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.flush(); printWriter.close(); String result = writer.toString(); sb.append(result); writeFile(sb.toString()); } catch (Exception e) { Log.e(TAG, "an error occurred while writing file...", e); sb.append("an error occurred while writing file...\r\n"); writeFile(sb.toString()); } } private void writeFile(String sb) throws Exception { String time = formatter.format(new Date()); String fileName = "crash-" + time + ".txt"; if (hasSdcard()) { String path = getGlobalPath(); File dir = new File(path); if (!dir.exists()) dir.mkdirs(); FileOutputStream fos = new FileOutputStream(path + fileName, true); fos.write(sb.getBytes()); fos.flush(); fos.close(); } } // 异常log生存路径 private String getGlobalPath() { return mContext.getExternalFilesDir("").getAbsolutePath() + "/Crash/"; } // 判断是否存在sd卡 private boolean hasSdcard() { return Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED); }}
复制代码
- 自界说一个继续Application的全局入口MyApplication,注册异常处理类。
- public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); CrashHandler.getInstance().init(this); }}
复制代码
- 在AndroidManifest.xml文件中注册自界说的Application。
来源:https://blog.csdn.net/tracydragonlxy/article/details/107832581
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |