在用户使用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));