CrashHandler.java 5.9 KB

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