1. 程式人生 > >Android 捕獲crash

Android 捕獲crash

在使用者使用Android應用過程中,可能發生一些意想不到的問題,開發工程師無法完全處理所有問題,而且這些問題藏的比較深,測試也沒有測試出來。

如果導致崩潰勢必影響使用者的使用,而且工程師需要這些異常的資訊來修復bug。使用我們需要處理這樣的異常。

方法如下:

1、實現自己的UncaughtExceptionHandler。

在這個UncaughtExceptionHandler裡收集需要的資訊(最終傳送到伺服器等等,...這裡只把資訊記錄了下來)。

/***
 * 系統崩潰 */
public class MyCrashHandler implements UncaughtExceptionHandler {

    private 
Context mContext; private String CRASH_DIRECTORY = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +"crash"; // 用來儲存裝置資訊和異常資訊 private Map<String, String> infos = new HashMap<String,
String>(); // 用於格式化日期,作為日誌檔名的一部分 private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); public MyCrashHandler(Context context) { this.mContext = context; } @Override public void uncaughtException(Thread thread, Throwable ex) { try { // 收集裝置引數資訊
collectDeviceInfo(mContext); // 儲存日誌檔案 saveCrashInfo2File(ex); } catch (Exception e) { e.printStackTrace(); }// 重新啟動程式,註釋上面的退出程式 Intent intent = new Intent(); intent.setClass(mContext, MainActivity.class); intent.putExtra("flag", "crash"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); mContext.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid()); } /** * 收集裝置引數資訊 * * @param ctx */ public void collectDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (NameNotFoundException e) { LogUtils.e("an error occured when collect package info" + e.toString()); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString()); LogUtils.d(field.getName() + " : " + field.get(null)); } catch (Exception e) { LogUtils.e("an error occured when collect crash info" + e.toString()); } } } /** * 儲存錯誤資訊到檔案中 * * @param ex */ private void saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\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.close(); String result = writer.toString(); sb.append(result); try { LogUtils.e("crash -- " + sb.toString()); long timestamp = System.currentTimeMillis(); String time = formatter.format(new Date()); String fileName = time + "-" + timestamp + ".log"; //將錯誤日誌儲存在sdcard/crash/中 FileStorage fileStorage = new FileStorage(); fileStorage.savePublic(CRASH_DIRECTORY, fileName,sb.toString().getBytes()); } catch (Exception e) { LogUtils.e("an error occured while writing file..." + e.toString()); } } }

2、在Application中設定用我們自己定義的UncaughtExceptionHandler來處理崩潰異常。

//程式崩潰
Thread.setDefaultUncaughtExceptionHandler(new MyCrashHandler(this));