package com.lan.nicehair.app; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import android.os.Looper; import android.util.Log; import android.widget.Toast; import com.lan.nicehair.utils.PathUtil; import com.lan.nicehair.utils.StringUtil; /** * @brief 异常崩溃处理类 * @details 当程序发生未捕获异常时,由该类来接管程序并记录发送错误报告。 */ public class CrashHandler implements UncaughtExceptionHandler { /** 错误日志文件名称 */ static final String LOG_NAME = "/crash.txt"; /** 系统默认的UncaughtException处理类 */ private Thread.UncaughtExceptionHandler mDefaultHandler; InitApplication application; /** * @brief 构造函数 * @details 获取系统默认的UncaughtException处理器,设置该CrashHandler为程序的默认处理器 。 * @param context 上下文 */ public CrashHandler(InitApplication application) { mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); this.application = application; } /** * @brief 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { // 如果用户没有处理则让系统默认的异常处理器来处理 if (!handleException(ex) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } else { // 等待会后结束程序 try { Log.i(LOG_NAME,"exit start"); Thread.sleep(3000); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); // Intent intent = new Intent(application.getApplicationContext(), MainActivity.class); // PendingIntent restartIntent = PendingIntent.getActivity( // application.getApplicationContext(), 0, intent, // Intent.FLAG_ACTIVITY_NEW_TASK); // //退出程序 // AlarmManager mgr = (AlarmManager)application.getSystemService(Context.ALARM_SERVICE); // mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, // restartIntent); // 1秒钟后重启应用 application.finishActivity(); Log.i(LOG_NAME,"exit end"); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * @brief 自定义错误处理,收集错误信息 * @details 发送错误报告等操作均在此完成 * @param ex 异常 * @return true:如果处理了该异常信息;否则返回false。 */ private boolean handleException(final Throwable ex) { if (ex == null) { return true; } ex.printStackTrace(); // 提示错误消息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(application.getApplicationContext(), "应用发生异常,即将退出!", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); // 保存错误报告文件 saveCrashInfoToFile(ex); return true; } /** * @brief 保存错误信息到文件中 * @param ex 异常 */ private void saveCrashInfoToFile(Throwable ex) { final StackTraceElement[] stack = ex.getStackTrace(); final String message = ex.getMessage(); /* 准备错误日志文件 */ File logFile = new File(PathUtil.APP_LOG_PATH + LOG_NAME); if (!logFile.getParentFile().exists()) { logFile.getParentFile().mkdirs(); } /* 写入错误日志 */ FileWriter fw = null; final String lineFeed = "\r\n"; try { fw = new FileWriter(logFile, true); fw.write(StringUtil.currentTime(StringUtil.FORMAT_YMDHMS).toString() + lineFeed + lineFeed); fw.write(message + lineFeed); for (int i = 0; i < stack.length; i++) { fw.write(stack[i].toString() + lineFeed); } fw.write(lineFeed); fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != fw) fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }