-
創建類
public class CrashHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "CrashHandler"; private Context mContext; private static CrashHandler mInstance; private Thread.UncaughtExceptionHandler mDefaultHandler; // 用來存儲設備信息和異常信息 private Map<String, String> mInfo = new HashMap<>(); private DateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private CrashHandler() {} public static CrashHandler getInstance() { if (mInstance == null) { synchronized (CrashHandler.class) { if (mInstance == null) { mInstance = new CrashHandler(); } } } return mInstance; } public void init(Context context) { mContext = context; // 獲取系統默認的UncaughtException處理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //設置該CrashHandler爲程序的默認處理器 Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread t, Throwable e) { // 如果用戶沒有處理則讓系統默認的異常處理器來處理 if (!handleException(e) && mDefaultHandler != null) { mDefaultHandler.uncaughtException(t, e); } else { try { Thread.sleep(3000); } catch (InterruptedException e1) { Log.e(TAG, "error", e); } // 退出程序 Process.killProcess(Process.myPid()); System.exit(1); } } // 自定義錯誤處理,收集錯誤信息,發送錯誤報告等操作均在此完成. private boolean handleException(Throwable e) { if (e == null) { return false; } // 使用Toast來顯示異常信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "很抱歉,程序出現異常,即將退出.", Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); //收集設備參數信息 collectErrorInfo(); //保存日誌文件 saveErrorInfo(e); return true; } // 收集設備參數信息 private void collectErrorInfo() { PackageManager pm = mContext.getPackageManager(); try { PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = TextUtils.isEmpty(pi.versionName) ? "未設置版本號" : pi.versionName; String versionCode = pi.versionCode + ""; mInfo.put("versionName", versionName); mInfo.put("versionCode", versionCode); } Field[] fields = Build.class.getFields(); if (fields != null && fields.length > 0) { for (Field field : fields) { field.setAccessible(true); try { mInfo.put(field.getName(), field.get(null).toString()); } catch (IllegalAccessException e) { Log.e(TAG, "an error occured when collect crash info", e); } } } } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "an error occured when collect package info", e); } } // 保存錯誤信息到文件中 private void saveErrorInfo(Throwable e) { StringBuffer stringBuffer = new StringBuffer(); for (Map.Entry<String, String> entry : mInfo.entrySet()) { String keyName = entry.getKey(); String value = entry.getKey(); stringBuffer.append(keyName+"="+value+"\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); e.printStackTrace(printWriter); Throwable cause = e.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); stringBuffer.append(result); long currentTime = System.currentTimeMillis(); String time = mDateFormat.format(new Date()); String fileName = "crash-" + time + "-" + currentTime + ".log"; // 判斷有沒有SD卡 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/shanghaicrash"); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = null; try { fos = new FileOutputStream(dir + "/" + fileName); fos.write(stringBuffer.toString().getBytes()); } catch (FileNotFoundException e1) { Log.e(TAG, "an error occured due to file not found", e); } catch (IOException e2) { Log.e(TAG, "an error occured while writing file...", e); } finally { try { fos.close(); } catch (IOException e1) { Log.e(TAG, "an error occured when close file", e); } } } } }
-
在application中初始化
CrashHandler.getInstance().init(this);
-
在設定的位置查看log
android 全局crash
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.