[2016-06-30]最新的全局异常处理DRCrashHandler已经集成在DR_support_lib库中

具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/tree/master

[2016-06-28] 1 增加log4j的支持
[2016-06-28] 2 增加全局异常处理(可自定义程序崩溃提示消息,自定义发送错误报告到服务器)
[2016-06-28] 3 增加两种应用退出方法:① appExit,结束掉所有Acitivity的生命周期,正常退出;② appKill,结束掉所有Acitivity的生命周期,杀掉程序进程后退出。
[2016-06-29] 4 增加透明状态栏和导航栏(默认开启,蓝色背景)

在Android程序中,我们通常会在可能发生错误的地方加上try {} catch (Exception e) {}语句来捕获异常,但是,我们无法保证程序就一定不会出错,比如,你玩Android游戏的过程中经常会碰到黑屏或者直接退出的情况,那么这些异常就应该是没有被捕获到(一般获取到都会提示用户错误,并提示用户是否将错误上传至服务器),那么现在我们来看下如何捕获全局异常,然后自己处理。

1、新建DRCrashHandler.java(这是一个抽象类,我放在了DR_supprot_lib库中,以便以后再写应用程序的时候直接使用,里面用到了一些变量是DRConstants类中的,这是一个常量类,用来定义常用的常量的)

默认Toast弹窗提示用户(消息可以自定义)

  1. package cn.dr.lib.app;
  2.  
  3. import java.io.File;
  4. import java.io.PrintWriter;
  5. import java.io.StringWriter;
  6. import java.io.Writer;
  7. import java.lang.Thread.UncaughtExceptionHandler;
  8. import java.lang.reflect.Field;
  9. import java.util.Date;
  10. import java.util.HashMap;
  11. import java.util.Locale;
  12. import java.util.Map;
  13.  
  14. import org.apache.log4j.Logger;
  15.  
  16. import android.content.Context;
  17. import android.content.pm.PackageInfo;
  18. import android.content.pm.PackageManager;
  19. import android.content.pm.PackageManager.NameNotFoundException;
  20. import android.os.Build;
  21. import android.os.Looper;
  22. import android.widget.Toast;
  23. import cn.dr.lib.common.DRConstants;
  24. import cn.dr.lib.utils.DateUtil;
  25. import cn.dr.lib.utils.FileUtil;
  26.  
  27. /**
  28. * DarkRanger的全局异常处理类
  29. *
  30. * @author DarkRanger
  31. *
  32. */
  33. public abstract class DRCrashHandler implements UncaughtExceptionHandler {
  34.  
  35. /** log4j **/
  36. private static final Logger log = Logger.getLogger(DRCrashHandler.class);
  37.  
  38. /** 系统默认的UncaughtException处理类 **/
  39. private Thread.UncaughtExceptionHandler mDefaultHandler;
  40.  
  41. /** 程序context **/
  42. private DRApplication mContext;
  43.  
  44. /** 存储设备信息和异常信息 **/
  45. private Map<String, String> mInfos = new HashMap<String, String>();
  46.  
  47. /** 程序出错提示信息 **/
  48. private String mDRTipMsg = "抱歉,程序异常,3s后退出!";
  49.  
  50. /** 设置crash文件位置 **/
  51. private String mDRCrashFilePath = DRConstants.CRASH_FILE_PATH;
  52.  
  53. /** 生成的log文件 **/
  54. private File logFile;
  55.  
  56. /** 生成的crash文件 **/
  57. private File crashFile;
  58.  
  59. /**
  60. * 初始化
  61. *
  62. * @param context
  63. */
  64. public void init(DRApplication context) {
  65. log.info("DRCrashHandler is Ready For Application! ");
  66.  
  67. // 1、上下文
  68. mContext = context;
  69.  
  70. // 2、获取系统默认的UncaughtException处理器
  71. mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  72.  
  73. // 3、初始化参数
  74. initParams();
  75.  
  76. // 4、设置当前CrashHandler为默认处理异常类
  77. Thread.setDefaultUncaughtExceptionHandler(this);
  78. }
  79.  
  80. /**
  81. * 3.1 初始化参数 <br/>
  82. * <br/>
  83. *
  84. * {@link #setTipMsg(String)} setTipMsg("this is crash tip msg!!!"); <br/>
  85. * {@link #setCrashFilePath(String)}
  86. * setCrashFilePath(Constants.CRASH_FILE_PATH); <br/>
  87. * <br/>
  88. *
  89. * 如果想使用自己的CrashHandler,则复写initParams()方,然后设置参数<br/>
  90. *
  91. * <code>
  92. * public class MyCrashHandler extends DRCrashHandler {<br/>
  93. * private static final Logger log = Logger.getLogger(MyCrashHandler.class);<br/>
  94. *
  95. * @Override<br/>
  96. * public void initParams() {<br/>
  97. * log.trace("MyCrashHandler: initParams()");<br/>
  98. *
  99. * setDRTipMsg("MyCrashHandler tip msg!!!");<br/>
  100. * setDRCrashFilePath(Constants.CRASH_FILE_PATH);<br/>
  101. * }<br/>
  102. * }<br/>
  103. * </code>
  104. */
  105. public abstract void initParams();
  106.  
  107. @Override
  108. public void uncaughtException(Thread thread, Throwable ex) {
  109. log.info("DRCrashHandler dispatcher uncaughtException! ");
  110.  
  111. if (mDefaultHandler != null && !handlerException(ex)) {
  112. mDefaultHandler.uncaughtException(thread, ex);
  113. } else {
  114. // 程序休眠3s后退出
  115. try {
  116. Thread.sleep(3000);
  117. } catch (InterruptedException e) {
  118. e.printStackTrace();
  119. }
  120.  
  121. ((DRApplication) mContext.getApplicationContext()).appExit();
  122. }
  123.  
  124. }
  125.  
  126. /**
  127. * 5、处理异常<br>
  128. * <br>
  129. *
  130. * 5.1 收集设备参数信息<br>
  131. * 5.2 弹出窗口提示信息<br>
  132. * 5.3 保存log和crash到文件<br>
  133. * 5.4 发送log和crash到服务器<br>
  134. *
  135. * @param ex
  136. * @return 是否处理了异常
  137. */
  138. protected boolean handlerException(Throwable ex) {
  139. log.info("DRCrashHandler is handling Exception! ");
  140.  
  141. if (ex == null) {
  142. return false;
  143. } else {
  144.  
  145. // 5.1 收集设备参数信息
  146. collectDeviceInfo(mContext);
  147.  
  148. // 5.2 弹出窗口提示信息
  149. new Thread(new Runnable() {
  150. public void run() {
  151. log.info("DRCrashHandler is ready send crash-info to device!");
  152.  
  153. Looper.prepare();
  154. Toast.makeText(mContext, getDRTipMsg(), Toast.LENGTH_SHORT).show();
  155. Looper.loop();
  156. }
  157. }).start();
  158.  
  159. // 5.3 保存log和crash到文件
  160. saveLogAndCrash(ex);
  161. // 5.4 发送log和crash到服务器
  162. sendLogAndCrash();
  163.  
  164. return true;
  165. }
  166.  
  167. }
  168.  
  169. /**
  170. * 5.1 收集设备信息
  171. *
  172. * @param ctx
  173. */
  174. protected void collectDeviceInfo(Context ctx) {
  175. log.info("DRCrashHandler is collecting DeviceInfo! ");
  176.  
  177. try {
  178. PackageManager pm = ctx.getPackageManager();
  179. PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
  180. if (pi != null) {
  181. String versionName = pi.versionName == null ? "null" : pi.versionName;
  182. String versionCode = pi.versionCode + "";
  183. mInfos.put("versionName", versionName);
  184. mInfos.put("versionCode", versionCode);
  185. }
  186. } catch (NameNotFoundException e) {
  187. log.error("An error occured when collect package info, Error: " + e);
  188. }
  189. Field[] fields = Build.class.getDeclaredFields();
  190. for (Field field : fields) {
  191. try {
  192. field.setAccessible(true);
  193. mInfos.put(field.getName(), field.get(null).toString());
  194. } catch (Exception e) {
  195. log.error("An error occured when collect crash info, Error: " + e);
  196. }
  197. }
  198. }
  199.  
  200. /**
  201. * 5.3 保存log和crash到文件
  202. *
  203. * @param ex
  204. */
  205. protected void saveLogAndCrash(Throwable ex) {
  206. log.info("DRCrashHandler is saving Log! ");
  207.  
  208. StringBuffer sb = new StringBuffer();
  209.  
  210. sb.append("[DateTime: " + DateUtil.date2String(new Date()) + "]\n");
  211. sb.append("[DeviceInfo: ]\n");
  212. // 遍历infos
  213. for (Map.Entry<String, String> entry : mInfos.entrySet()) {
  214. String key = entry.getKey().toLowerCase(Locale.getDefault());
  215. String value = entry.getValue();
  216. sb.append(" " + key + ": " + value + "\n");
  217. }
  218. // 将错误手机到writer中
  219. Writer writer = new StringWriter();
  220. PrintWriter pw = new PrintWriter(writer);
  221. ex.printStackTrace(pw);
  222. Throwable cause = ex.getCause();
  223. while (cause != null) {
  224. cause.printStackTrace(pw);
  225. cause = cause.getCause();
  226. }
  227. pw.close();
  228. String result = writer.toString();
  229. sb.append("[Excetpion: ]\n");
  230. sb.append(result);
  231.  
  232. // 将异常写入日志文件
  233. log.error(result);
  234.  
  235. // 5.3.1 记录异常到特定文件中
  236. saveToCrashFile(sb.toString());
  237.  
  238. }
  239.  
  240. /**
  241. * 5.3.1写入文本
  242. *
  243. * @param crashText
  244. */
  245. protected void saveToCrashFile(String crashText) {
  246. log.info("DRCrashHandler is writing crash-info to CrashFile(" + this.mDRCrashFilePath + ")! ");
  247.  
  248. crashFile = new File(mDRCrashFilePath);
  249.  
  250. // 创建文件(自己写的操作文件相关的工具类)
  251. FileUtil.createFileAndFolder(crashFile);
  252.  
  253. // 追加文本(自己写的操作文件相关的工具类)
  254. FileUtil.appendToFile(crashFile, crashText);
  255.  
  256. }
  257.  
  258. /**
  259. * 5.4 发送log和crash到服务器
  260. */
  261. protected void sendLogAndCrash() {
  262. logFile = new File(mContext.getDrLogHelper().getLog4jFilePath());
  263. crashFile = new File(getDRCrashFilePath());
  264. // 5.4.1
  265. sendToServer(logFile, crashFile);
  266. }
  267.  
  268. /**
  269. * 5.4.1 将错误报告发送到服务器
  270. *
  271. * @param crashFile
  272. * @param logFile
  273. */
  274. protected abstract void sendToServer(File logFile, File crashFile);
  275.  
  276. public String getDRTipMsg() {
  277. return mDRTipMsg;
  278. }
  279.  
  280. /**
  281. * 设置程序崩溃提示信息
  282. *
  283. * @param mDRTipMsg
  284. */
  285. public void setDRTipMsg(String mDRTipMsg) {
  286. this.mDRTipMsg = mDRTipMsg;
  287. }
  288.  
  289. public String getDRCrashFilePath() {
  290. return mDRCrashFilePath;
  291. }
  292.  
  293. /**
  294. * 设置记录崩溃信息的文件位置
  295. *
  296. * @param mDRCrashFilePath
  297. */
  298. public void setDRCrashFilePath(String mDRCrashFilePath) {
  299. this.mDRCrashFilePath = mDRCrashFilePath;
  300. }
  301.  
  302. }

2、新建DRApplication.java(抽象类,里面用到了Log4j,上一篇有讲到如果在Android中集成Log4j,这里在Application中使用DRLogHelper来初始化log4j)

  1. package cn.dr.lib.app;
  2.  
  3. import java.io.File;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6.  
  7. import org.apache.log4j.Logger;
  8.  
  9. import android.app.Activity;
  10. import android.app.Application;
  11. import cn.dr.lib.log.DRLogHelper;
  12. import cn.dr.lib.ui.DRAcitivity;
  13.  
  14. /**
  15. * DarkRanger的Application
  16. *
  17. * @author DarkRanger
  18. *
  19. */
  20. public abstract class DRApplication extends Application {
  21.  
  22. // 当前类的log
  23. private static Logger log;
  24.  
  25. // Activity列表
  26. private List<DRAcitivity> mActivityList = new LinkedList<DRAcitivity>();
  27.  
  28. // drLog实例
  29. public DRLogHelper mDRLogHelper = DRLogHelper.getInstance();
  30.  
  31. // 全局异常处理类的实例
  32. public DRCrashHandler mDRCrashHandler = new DRCrashHandler() {
  33.  
  34. @Override
  35. public void initParams() {
  36.  
  37. }
  38.  
  39. @Override
  40. public void sendToServer(File logFile, File crashFile) {
  41.  
  42. }
  43.  
  44. };
  45.  
  46. @Override
  47. public void onCreate() {
  48.  
  49. super.onCreate();
  50.  
  51. // 1、初始化DRLog参数
  52. initDRLogHelperParam();
  53.  
  54. // 2、初始化DRLog
  55. initDRLogHelper();
  56.  
  57. // 3、初始化全局异常处理类
  58. initCrashHandler();
  59. }
  60.  
  61. /**
  62. * 1、初始化DRLog参数,如: <br/>
  63. *
  64. * {@link DRApplication#getDrlog()} DRLog drLog = getDrlog(); <br/>
  65. * {@link DRLogHelper#setLog4jFilePath(String)}
  66. * drLog.setLog4jFilePath(Constants.LOG4J_FILE_PATH); <br/>
  67. * {@link DRLogHelper#setType(cn.dr.lib.log.DRLogHelper.LogType)}
  68. * drLog.setType(LogType.TYPE_LOG4J); <br/>
  69. *
  70. * 只有在子类中完成initDRLogParam参数设置以后才能使用log
  71. */
  72. protected abstract void initDRLogHelperParam();
  73.  
  74. /**
  75. * 2、初始化DRLog
  76. */
  77. private void initDRLogHelper() {
  78. getDrLogHelper().init();
  79.  
  80. log = Logger.getLogger(DRApplication.class);
  81. }
  82.  
  83. /**
  84. * 3、初始化CrashHandler
  85. */
  86. private void initCrashHandler() {
  87. log.trace("DRApplication: initCrashHandler()");
  88.  
  89. // 3.1
  90. setHandler();
  91.  
  92. // 3.2
  93. getDRCrashHandler().init(this);
  94. }
  95.  
  96. /**
  97. *
  98. * 3.1 调用以下方法为mCrashHandler设置实例<br/>
  99. * <br/>
  100. *
  101. * {@link #setCrashHandler(DRCrashHandler)}
  102. */
  103. public abstract void setHandler();
  104.  
  105. /**
  106. * 获取DRLog单例
  107. *
  108. * @return
  109. */
  110. public DRLogHelper getDrLogHelper() {
  111. return mDRLogHelper;
  112. }
  113.  
  114. public DRCrashHandler getDRCrashHandler() {
  115. return mDRCrashHandler;
  116. }
  117.  
  118. public void setDRCrashHandler(DRCrashHandler mCrashHandler) {
  119. this.mDRCrashHandler = mCrashHandler;
  120. }
  121.  
  122. /**
  123. * 添加activity到App的mActivityList
  124. *
  125. * @param activity
  126. */
  127. public void addActivity(DRAcitivity activity) {
  128. this.mActivityList.add(activity);
  129. }
  130.  
  131. /**
  132. * 遍历mActivityList,结束每一个activity的声明周期
  133. */
  134. private void finishActivityList() {
  135. for (Activity activity : mActivityList) {
  136. activity.finish();
  137. }
  138. }
  139.  
  140. @Override
  141. public void onTerminate() {
  142. log.trace("DRApplication: onTerminate()");
  143.  
  144. super.onTerminate();
  145. appExit();
  146. }
  147.  
  148. /**
  149. * 完全退出程序
  150. */
  151. public void appExit() {
  152. log.trace("DRApplication: appExit()");
  153.  
  154. finishActivityList();
  155. // 正常退出
  156. System.exit(0);
  157. }
  158.  
  159. /**
  160. * 出现异常杀掉进程
  161. */
  162. public void appKill() {
  163. log.trace("DRApplication: appKill()");
  164.  
  165. finishActivityList();
  166. android.os.Process.killProcess(android.os.Process.myPid());
  167. System.exit(1);
  168. }
  169.  
  170. }

3、

首先要说明的是:前面两个类我已经集成在DR_supprot_lib库中,在新的应用程序中只需要继承这两个类,分类初始化一些参数即可。

写个App程序测试:

3.1 新建MyCrashHandler.java继承DRCrashHandler,复写两个抽象方法initParams()和sendToServer()

  1. package cn.darkranger.test;
  2.  
  3. import java.io.File;
  4.  
  5. import org.apache.log4j.Logger;
  6.  
  7. import android.os.Environment;
  8. import cn.dr.lib.app.DRCrashHandler;
  9.  
  10. public class MyCrashHandler extends DRCrashHandler {
  11. private static final Logger log = Logger.getLogger(MyCrashHandler.class);
  12.  
  13. String crashFilePath = Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator
  14. + "Crash.txt";
  15.  
  16. @Override
  17. public void initParams() {
  18. // 设置程序崩溃提示信息
  19. setDRTipMsg("this is my msg - -");
  20. // 设置程序崩溃的文件位置
  21. setDRCrashFilePath(crashFilePath);
  22. }
  23.  
  24. @Override
  25. protected void sendToServer(File logFile, File crashFile) {
  26. log.info("logFile: " + logFile + "; crashFile: " + "\naction:sendToServer - -");
  27. // 这里要写上传错误信息到服务器的代码,暂时不写,看需求,自己实现
  28. }
  29.  
  30. }

3.2 新建MyApplication.java继承DRApplication,复写两个抽象方法initDRLogHelperParam()和setHandler()

  1. package cn.darkranger.test;
  2.  
  3. import java.io.File;
  4.  
  5. import org.apache.log4j.Logger;
  6.  
  7. import android.os.Environment;
  8. import cn.dr.lib.app.DRCrashHandler;
  9.  
  10. public class MyCrashHandler extends DRCrashHandler {
  11. private static final Logger log = Logger.getLogger(MyCrashHandler.class);
  12.  
  13. String crashFilePath = Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator
  14. + "Crash.txt";
  15.  
  16. @Override
  17. public void initParams() {
  18. // 设置程序崩溃提示信息
  19. setDRTipMsg("this is my msg - -");
  20. // 设置程序崩溃的文件位置
  21. setDRCrashFilePath(crashFilePath);
  22. }
  23.  
  24. @Override
  25. protected void sendToServer(File logFile, File crashFile) {
  26. log.info("logFile: " + logFile + "; crashFile: " + "\naction:sendToServer - -");
  27. // 这里要写上传错误信息到服务器的代码,暂时不写,看需求,自己实现
  28. }
  29.  
  30. }

3.3 新建MainActivity,这里暂时不继承DRActivity,继承AppCompatActivity,两个testview,点击第一个,调用DRApplication的退出,点击第二个,抛出异常,我们自己捕获。

  1. package cn.darkranger.test;
  2.  
  3. import android.os.Bundle;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.view.Menu;
  6. import android.view.MenuItem;
  7. import android.view.View;
  8. import android.view.View.OnClickListener;
  9. import android.widget.TextView;public class MainActivity extends AppCompatActivity {
  10.  
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15.  
  16. TextView exitTv = (TextView) findViewById(R.id.id_exit);
  17. exitTv.setOnClickListener(new OnClickListener() {
  18.  
  19. @Override
  20. public void onClick(View v) {
  21. ((MyApplication) getApplication()).appExit();
  22. }
  23. });
  24.  
  25. TextView testCrashTv = (TextView) findViewById(R.id.id_testCrash);
  26. testCrashTv.setOnClickListener(new OnClickListener() {
  27.  
  28. @Override
  29. public void onClick(View v) {
  30. throw new IllegalArgumentException("this is an IllegalArgumentException! ");
  31. }
  32. });
  33.  
  34. }
  35.  
  36. @Override
  37. public boolean onCreateOptionsMenu(Menu menu) {
  38. getMenuInflater().inflate(R.menu.main, menu);
  39. return true;
  40. }
  41.  
  42. @Override
  43. public boolean onOptionsItemSelected(MenuItem item) {
  44. int id = item.getItemId();
  45. if (id == R.id.action_settings) {
  46. return true;
  47. }
  48. return super.onOptionsItemSelected(item);
  49. }
  50. }

3.4 更改AndroidManifest.xml(添加读写文件的权限,设置application为:cn.darkranger.test.MyApplication)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="cn.darkranger.test"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk
  8. android:minSdkVersion="11"
  9. android:targetSdkVersion="21" />
  10.  
  11. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  12. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  13.  
  14. <application
  15. android:name="cn.darkranger.test.MyApplication"
  16. android:allowBackup="true"
  17. android:icon="@drawable/ic_launcher"
  18. android:label="@string/app_name"
  19. android:theme="@style/AppTheme" >
  20. <activity
  21. android:name=".MainActivity"
  22. android:label="@string/app_name" >
  23. <intent-filter>
  24. <action android:name="android.intent.action.MAIN" />
  25.  
  26. <category android:name="android.intent.category.LAUNCHER" />
  27. </intent-filter>
  28. </activity>
  29. </application>
  30.  
  31. </manifest>

测试:

运行,点击第一个按钮,退出程序,查看log文件:

  1. [2016-06-30 22:19:09][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
  2. [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
  3.  
  4. [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
  5. [Level: TRACE] - Msg: DRApplication: initCrashHandler()
  6.  
  7. [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
  8. [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
  9.  
  10. [2016-06-30 22:19:12][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
  11. [Level: TRACE] - Msg: DRApplication: appExit()
  12.  
  13. [2016-06-30 22:19:58][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
  14. [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
  15.  
  16. [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
  17. [Level: TRACE] - Msg: DRApplication: initCrashHandler()
  18.  
  19. [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
  20. [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
  21.  
  22. [2016-06-30 22:20:02][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
  23. [Level: TRACE] - Msg: DRApplication: appExit()

运行,点击第二个按钮,抛出异常,查看log文件和crash文件:

Log.txt

  1. [2016-06-30 22:19:09][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
  2. [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
  3.  
  4. [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
  5. [Level: TRACE] - Msg: DRApplication: initCrashHandler()
  6.  
  7. [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
  8. [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
  9.  
  10. [2016-06-30 22:19:12][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
  11. [Level: TRACE] - Msg: DRApplication: appExit()
  12.  
  13. [2016-06-30 22:19:58][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
  14. [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
  15.  
  16. [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
  17. [Level: TRACE] - Msg: DRApplication: initCrashHandler()
  18.  
  19. [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
  20. [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
  21.  
  22. [2016-06-30 22:20:02][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
  23. [Level: TRACE] - Msg: DRApplication: appExit()
  24.  
  25. [2016-06-30 22:20:48][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
  26. [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
  27.  
  28. [2016-06-30 22:20:48][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
  29. [Level: TRACE] - Msg: DRApplication: initCrashHandler()
  30.  
  31. [2016-06-30 22:20:48][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
  32. [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
  33.  
  34. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.uncaughtException(DRCrashHandler.java:109)]
  35. [Level: INFO ] - Msg: DRCrashHandler dispatcher uncaughtException!
  36.  
  37. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.handlerException(DRCrashHandler.java:139)]
  38. [Level: INFO ] - Msg: DRCrashHandler is handling Exception!
  39.  
  40. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.collectDeviceInfo(DRCrashHandler.java:175)]
  41. [Level: INFO ] - Msg: DRCrashHandler is collecting DeviceInfo!
  42.  
  43. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveLogAndCrash(DRCrashHandler.java:206)]
  44. [Level: INFO ] - Msg: DRCrashHandler is saving Log!
  45.  
  46. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.run(DRCrashHandler.java:151)]
  47. [Level: INFO ] - Msg: DRCrashHandler is ready send crash-info to device!
  48.  
  49. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveLogAndCrash(DRCrashHandler.java:233)]
  50. [Level: ERROR] - Msg: java.lang.IllegalArgumentException: this is an IllegalArgumentException!
  51. at cn.darkranger.test.MainActivity$2.onClick(MainActivity.java:33)
  52. at android.view.View.performClick(View.java:4792)
  53. at android.view.View$PerformClick.run(View.java:19936)
  54. at android.os.Handler.handleCallback(Handler.java:739)
  55. at android.os.Handler.dispatchMessage(Handler.java:95)
  56. at android.os.Looper.loop(Looper.java:135)
  57. at android.app.ActivityThread.main(ActivityThread.java:5595)
  58. at java.lang.reflect.Method.invoke(Native Method)
  59. at java.lang.reflect.Method.invoke(Method.java:372)
  60. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
  61. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
  62.  
  63. [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveToCrashFile(DRCrashHandler.java:246)]
  64. [Level: INFO ] - Msg: DRCrashHandler is writing crash-info to CrashFile(/storage/emulated/0/MyApp/Crash.txt)!
  65.  
  66. [2016-06-30 22:20:50][Class: cn.dr.lib.utils.FileUtil.createFileAndFolder(FileUtil.java:444)]
  67. [Level: INFO ] - Msg: File[/storage/emulated/0/MyApp/Crash.txt] was created successfully!
  68.  
  69. [2016-06-30 22:20:50][Class: cn.darkranger.test.MyCrashHandler.sendToServer(MyCrashHandler.java:26)]
  70. [Level: INFO ] - Msg: logFile: /storage/emulated/0/MyApp/Log.txt; crashFile:
  71. action:sendToServer - -
  72.  
  73. [2016-06-30 22:20:53][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
  74. [Level: TRACE] - Msg: DRApplication: appExit()

Crash.txt

  1. [DateTime: 2016-06-30 22:20:50]
  2. [DeviceInfo: ]
  3. supported_64_bit_abis: [Ljava.lang.String;@16d078ef
  4. versioncode: 1
  5. board: mozart
  6. bootloader: unknown
  7. type: user
  8. matchers: [Ljava.lang.String;@3d5b7685
  9. id: HUAWEIM2-801W
  10. time: 1437332391000
  11. brand: HUAWEI
  12. tag: Build
  13. serial: TJF4C15804003585
  14. hardware: hi3635
  15. supported_abis: [Ljava.lang.String;@33767ffc
  16. no_hota: false
  17. cpu_abi: arm64-v8a
  18. radio: unknown
  19. is_debuggable: false
  20. replacements: [Ljava.lang.String;@2dec2cda
  21. manufacturer: HUAWEI
  22. supported_32_bit_abis: [Ljava.lang.String;@3271c1ce
  23. tags: ota-rel-keys,release-keys
  24. cpu_abi2:
  25. unknown: unknown
  26. user: huawei
  27. fingerprint: HUAWEI/M2/HWMozart:5.1.1/HUAWEIM2-801W/C233B009:user/release-keys
  28. host: WUH1000005635
  29. product: M2
  30. versionname: 1.0
  31. display: M2-801WV100R001C233B009
  32. hide_product_info: false
  33. model: HUAWEI M2-801W
  34. device: HWMozart
  35. [Excetpion: ]
  36. java.lang.IllegalArgumentException: this is an IllegalArgumentException!
  37. at cn.darkranger.test.MainActivity$2.onClick(MainActivity.java:33)
  38. at android.view.View.performClick(View.java:4792)
  39. at android.view.View$PerformClick.run(View.java:19936)
  40. at android.os.Handler.handleCallback(Handler.java:739)
  41. at android.os.Handler.dispatchMessage(Handler.java:95)
  42. at android.os.Looper.loop(Looper.java:135)
  43. at android.app.ActivityThread.main(ActivityThread.java:5595)
  44. at java.lang.reflect.Method.invoke(Native Method)
  45. at java.lang.reflect.Method.invoke(Method.java:372)
  46. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
  47. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

Android应用捕获全局异常自定义处理的更多相关文章

  1. Android捕获全局异常

    Android捕获全局异常 程序避免不了出现bug,导致程序崩溃,为了尽量不影响用户体验,可以全局捕获异常 效果图 异常捕获处理前 异常捕获处理后(将程序重新启动) 捕获异常的工具类 package ...

  2. 在C#代码中应用Log4Net(四)在Winform和Web中捕获全局异常

    毕竟人不是神,谁写的程序都会有bug,有了bug不可怕,可怕的是出错了,你却不知道错误在哪里.所以我们需要将应用程序中抛出的所有异常都记录起来,不然出了错,找问题就能要了你的命.下面我们主要讨论的是如 ...

  3. C# 捕获全局异常

    一.在Winform程序中捕获全局异常 在winfrom中我们需要了解Application对象中的两个事件 ①Application.ThreadException 事件--当UI线程中某个异常未被 ...

  4. SpringBoot捕获全局异常

    1.创建GloableExceptionAop类捕获全局异常 package com.cppdy.exception; import org.springframework.web.bind.anno ...

  5. WebForm 在 Global.asax 中捕获全局异常

    /// <summary> /// 捕获全局异常 /// </summary> /// <param name="sender">sender& ...

  6. SpringBoot学习笔记(二):SpringBoot访问静态文件、捕获全局异常、集成Thymeleaf、集成JSP

    SpringBoot访问静态文件 什么是静态文件? 不需要通过web容器去得到的文件,直接通过路径就能得到的文件,比如项目的css,js,img等文件. 所有的资源文件都应该在src/main/res ...

  7. Android使用UncaughtExceptionHandler捕获全局异常

    Android系统的“程序异常退出”,给应用的用户体验造成不良影响.为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理.通过Thread.setDe ...

  8. 在Global.asax中 注册Application_Error事件 捕获全局异常

    参考于:https://shiyousan.com/post/635813858052755170 在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到 ...

  9. C# WinForm捕获全局异常

    网上找的C# WinForm全局异常捕获方法,代码如下: static class Program { /// <summary> /// 应用程序的主入口点. /// </summ ...

随机推荐

  1. 跨域问题hbuilder

    1.借助jquery-jsonp插件 $.jsonp({ url: url, data: { 'name': usd, 'passwd': pass }, callbackParameter: &qu ...

  2. App测试从入门到精通之兼容性和回归测试

    兼容性测试需要考虑的APP测试点 1.不同网络环境下的兼容性测试 2.不同手机操作系统兼容性测试 3.不同应用软件的兼容性测试 4.不同的容量大小的SIM卡之间的互相兼容测试 5.当安装杀毒软件时,应 ...

  3. C++ 中 dynamic_cast 浅析

    简述:dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用.主要讲解,dynamic_cast操作符的原理.使用方式.编译器设置.返回值等相关知识. dynamic_ca ...

  4. 【Linux-学习笔记-不定期更新】

    command--help ./当前的路径 目录操作命令: mkdir  创建目录: 创建多级目录 : mkdir -p 查看目录:ls ls -a:显示所有文件,包括隐藏文件 隐藏文件以.开头 ls ...

  5. C#多线程编程实战1.4终止线程

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  6. SOA IN Real World

    微软发布了一个名为“真实世界里的面向服务架构(SOA)”的电子书.这本书表达了微软对面向服务架构的观点,并包括了数个展示如何用微软产品和技术实现SOA的真实案例.书中解释到,SOA的功能型架构本身是松 ...

  7. react-native自定义原生组件

    此文已由作者王翔授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 使用react-native的时候能够看到不少函数调用式的组件,像LinkIOS用来呼起url请求  Link ...

  8. 主流C语言编译器介绍

  9. ubuntu 16.4安装toolsbelt heroku

    https://devcenter.heroku.com/articles/getting-started-with-python#set-up # Run this from your termin ...

  10. SpringMVC中视图解析器

    视图解析器:固定写法直接coppy就行 1.dispatcherServlet-servlet.xml中添加 <!-- 视图解析器InternalResourceViewResolver --& ...