CrashHandler.java 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package com.fxy.base;
  2. import android.content.Context;
  3. import android.content.SharedPreferences;
  4. import android.content.pm.PackageInfo;
  5. import android.content.pm.PackageManager;
  6. import android.os.Build;
  7. import com.alibaba.fastjson.JSONException;
  8. import org.json.JSONObject;
  9. import com.fxy.constant.SPCache;
  10. import com.lzy.okgo.OkGo;
  11. import com.lzy.okgo.model.Response;
  12. import com.fxy.baselibrary.util.RxTimeTool;
  13. import com.fxy.BuildConfig;
  14. import com.fxy.net.MyDialogCallback;
  15. import com.fxy.net.Urls;
  16. import java.io.PrintWriter;
  17. import java.io.StringWriter;
  18. import java.io.Writer;
  19. import java.lang.Thread.UncaughtExceptionHandler;
  20. public class CrashHandler implements UncaughtExceptionHandler {
  21. //系统默认的异常处理器
  22. private Thread.UncaughtExceptionHandler defaultCrashHandler;
  23. private static CrashHandler crashHandler = new CrashHandler();
  24. private Context mContext;
  25. //私有化构造函数
  26. private CrashHandler() {
  27. }
  28. //获取实例
  29. public static CrashHandler getInstance() {
  30. return crashHandler;
  31. }
  32. public void init(Context context) {
  33. mContext = context;
  34. defaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
  35. //设置系统的默认异常处理器
  36. Thread.setDefaultUncaughtExceptionHandler(this);
  37. }
  38. @Override
  39. public void uncaughtException(Thread thread, Throwable throwable) {
  40. //把错误信息保存在sp中,然后在下次进入页面的时候再上传错误信息
  41. saveErrorInfo(throwable);
  42. if (defaultCrashHandler != null) {
  43. //如果在自定义异常处理器之前,系统有自己的默认异常处理器的话,调用它来处理异常信息
  44. defaultCrashHandler.uncaughtException(thread, throwable);
  45. } else {
  46. android.os.Process.killProcess(android.os.Process.myPid());
  47. System.exit(0);
  48. }
  49. }
  50. public void sendError() {
  51. //先不发送
  52. try {
  53. SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
  54. String data = sp.getString("data", "");
  55. if (!data.isEmpty()) {
  56. JSONObject jsonObject = new JSONObject();
  57. jsonObject.put("content",data);
  58. OkGo.<String>post(Urls.getServiceAddress(mContext) +Urls.RECORD_LOG).upJson(jsonObject.toString())
  59. .execute(new MyDialogCallback(mContext, false, false) {
  60. @Override
  61. public void onSuccess(Response<String> response) {
  62. try {
  63. SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
  64. sp.edit().putString("data", "").apply();
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. }
  68. //XLog.e(response.body());
  69. }
  70. @Override
  71. public void onError(Response<String> response) {
  72. }
  73. });
  74. }
  75. } catch (JSONException | org.json.JSONException e) {
  76. e.printStackTrace();
  77. }
  78. }
  79. private void saveErrorInfo(Throwable throwable) {
  80. try {
  81. SharedPreferences sp = mContext.getSharedPreferences("errorInfo", Context.MODE_PRIVATE);
  82. SPCache spCache = SPCache.getInstance(mContext);
  83. String accountInfo = spCache.getUserName()+"("+spCache.getAccountName()+")";
  84. String stringBuffer = getAppInfo(mContext) +
  85. "崩溃本版:" + BuildConfig.BUILD_TYPE + "\n\n" +
  86. "崩溃时间:" + RxTimeTool.getCurTimeString() + "\n\n" +
  87. "设备系统:" + Build.VERSION.RELEASE + "\n\n" +
  88. "设备厂商:" + Build.MANUFACTURER + "\n\n" +
  89. "设备型号:" + Build.MODEL + "\n\n" +
  90. "账号信息:" + accountInfo + "\n\n" +
  91. "崩溃原因:" + throwable.getMessage() + "\n\n" +
  92. "详细信息:" + collectExceptionInfo(throwable);
  93. sp.edit().putString("data", stringBuffer).apply();
  94. } catch (Exception e) {
  95. e.printStackTrace();
  96. }
  97. }
  98. /**
  99. * 获取捕获异常的信息
  100. */
  101. private String collectExceptionInfo(Throwable ex) {
  102. try {
  103. Writer mWriter = new StringWriter();
  104. PrintWriter mPrintWriter = new PrintWriter(mWriter);
  105. ex.printStackTrace(mPrintWriter);
  106. ex.printStackTrace();
  107. Throwable mThrowable = ex.getCause();
  108. // 迭代栈队列把所有的异常信息写入writer中
  109. while (mThrowable != null) {
  110. mThrowable.printStackTrace(mPrintWriter);
  111. // 换行 每个个异常栈之间换行
  112. mPrintWriter.append("\r\n");
  113. mThrowable = mThrowable.getCause();
  114. }
  115. // 记得关闭
  116. mPrintWriter.close();
  117. return mWriter.toString();
  118. } catch (Exception e) {
  119. e.printStackTrace();
  120. return ex.getMessage();
  121. }
  122. }
  123. /**
  124. * 获取应用程序信息
  125. */
  126. public String getAppInfo(Context context) {
  127. try {
  128. PackageManager packageManager = context.getPackageManager();
  129. PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
  130. return "应用包名:" + packageInfo.packageName + "\n\n应用版本:" + packageInfo.versionName + "\n\n";
  131. } catch (Exception e) {
  132. e.printStackTrace();
  133. }
  134. return "";
  135. }
  136. }