Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.86 KB | None | 0 0
  1. import android.content.Context;
  2. import android.os.Looper;
  3. import android.util.Log;
  4. import android.widget.Toast;
  5.  
  6. import com.clock.utils.common.SystemUtils;
  7.  
  8. import java.io.File;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.io.OutputStreamWriter;
  12. import java.io.PrintWriter;
  13. import java.io.RandomAccessFile;
  14. import java.text.SimpleDateFormat;
  15. import java.util.Date;
  16.  
  17. /**
  18. * app奔溃异常处理器
  19. * <p/>
  20. * 使用此类需要在AndroidManifest.xml配置以下权限
  21. * <p/>
  22. * <bold>android.permission.READ_EXTERNAL_STORAGE</bold>
  23. * <p/>
  24. * <bold>android.permission.WRITE_EXTERNAL_STORAGE</bold>
  25. * <p/>
  26. * <bold>android.permission.READ_PHONE_STATE</bold>
  27. * <p/>
  28. * Created by Clock on 2016/1/24.
  29. */
  30. public class CrashExceptionHandler implements Thread.UncaughtExceptionHandler {
  31.  
  32. private final static String TAG = CrashExceptionHandler.class.getSimpleName();
  33.  
  34. private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmm");
  35.  
  36. private Context mApplicationContext;
  37. /**
  38. * 保存闪退日志的文件目录
  39. */
  40. private File mCrashInfoFolder;
  41. /**
  42. * 向远程服务器发送错误信息
  43. */
  44. private CrashExceptionRemoteReport mCrashExceptionRemoteReport;
  45.  
  46. /**
  47. * @param context
  48. * @param crashInfoFolder 保存闪退日志的文件夹目录
  49. */
  50. public CrashExceptionHandler(Context context, File crashInfoFolder) {
  51. this.mApplicationContext = context.getApplicationContext();
  52. this.mCrashInfoFolder = crashInfoFolder;
  53. }
  54.  
  55. @Override
  56. public void uncaughtException(Thread thread, Throwable ex) {
  57. ex.printStackTrace();
  58. handleException(ex);
  59. try {
  60. Thread.sleep(3000);
  61. } catch (InterruptedException e) {
  62. e.printStackTrace();
  63. }
  64. //杀死进程
  65. android.os.Process.killProcess(android.os.Process.myPid());
  66. }
  67.  
  68. /**
  69. * 配置远程传回log到服务器的设置
  70. *
  71. * @param crashExceptionRemoteReport
  72. */
  73. public void configRemoteReport(CrashExceptionRemoteReport crashExceptionRemoteReport) {
  74. this.mCrashExceptionRemoteReport = crashExceptionRemoteReport;
  75. }
  76.  
  77. /**
  78. * 处理异常
  79. *
  80. * @param ex
  81. */
  82. private void handleException(Throwable ex) {
  83. if (ex == null) {
  84. return;
  85. } else {
  86. saveCrashInfoToFile(ex);
  87. sendCrashInfoToServer(ex);
  88.  
  89. //使用Toast来显示异常信息
  90. new Thread() {
  91. @Override
  92. public void run() {
  93. Looper.prepare();
  94. try {
  95. Toast.makeText(mApplicationContext, "程序出现异常 , 即将退出....", Toast.LENGTH_LONG).show();
  96. } catch (Exception ex) {
  97. ex.printStackTrace();
  98. }
  99. Looper.loop();
  100. }
  101. }.start();
  102. }
  103. }
  104.  
  105. /**
  106. * 保存闪退信息到本地文件中
  107. *
  108. * @param ex
  109. */
  110. private void saveCrashInfoToFile(Throwable ex) {
  111. try {
  112. if (mCrashInfoFolder == null) {
  113. return;
  114. }
  115.  
  116. if (!mCrashInfoFolder.exists()) {//闪退日志目录不存在则先创建闪退日志目录
  117. mCrashInfoFolder.mkdirs();
  118. }
  119.  
  120. if (mCrashInfoFolder.exists()) {
  121. String timeStampString = DATE_FORMAT.format(new Date());//当先的时间格式化
  122. String crashLogFileName = timeStampString + ".log";
  123. File crashLogFile = new File(mCrashInfoFolder, crashLogFileName);
  124. crashLogFile.createNewFile();
  125.  
  126. //记录闪退环境的信息
  127. RandomAccessFile randomAccessFile = new RandomAccessFile(crashLogFile, "rw");
  128. randomAccessFile.writeChars("------------Crash Environment Info------------" + "\n");
  129. randomAccessFile.writeChars("------------Manufacture: " + SystemUtils.getDeviceManufacture() + "------------" + "\n");
  130. randomAccessFile.writeChars("------------DeviceName: " + SystemUtils.getDeviceName() + "------------" + "\n");
  131. randomAccessFile.writeChars("------------SystemVersion: " + SystemUtils.getSystemVersion() + "------------" + "\n");
  132. randomAccessFile.writeChars("------------DeviceIMEI: " + SystemUtils.getDeviceIMEI(mApplicationContext) + "------------" + "\n");
  133. randomAccessFile.writeChars("------------AppVersion: " + SystemUtils.getAppVersion(mApplicationContext) + "------------" + "\n");
  134. randomAccessFile.writeChars("------------Crash Environment Info------------" + "\n");
  135. randomAccessFile.writeChars("\n");
  136. randomAccessFile.close();
  137.  
  138. PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(crashLogFile.getAbsolutePath(), true)), true);
  139. ex.printStackTrace(pw);//写入奔溃的日志信息
  140. pw.close();
  141.  
  142. } else {
  143. Log.e(TAG, "crash info folder create failure!!!");
  144. }
  145.  
  146. } catch (IOException e) {
  147. e.printStackTrace();
  148. } catch (Exception e) {
  149. e.printStackTrace();
  150. }
  151. }
  152.  
  153. /**
  154. * 发送发送闪退信息到远程服务器
  155. *
  156. * @param ex
  157. */
  158. private void sendCrashInfoToServer(Throwable ex) {
  159. if (mCrashExceptionRemoteReport != null) {
  160. mCrashExceptionRemoteReport.onCrash(ex);
  161. }
  162. }
  163.  
  164. /**
  165. * 闪退日志远程奔溃接口,主要考虑不同app下,把log回传给服务器的方式不一样,所以此处留一个对外开放的接口
  166. */
  167. public static interface CrashExceptionRemoteReport {
  168. /**
  169. * 当闪退发生时,回调此接口函数
  170. *
  171. * @param ex
  172. */
  173. public void onCrash(Throwable ex);
  174. }
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement