1. package com.wlwl.yiyuan;
  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.text.DateFormat;
  10. import java.text.SimpleDateFormat;
  11. import java.util.Date;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14.  
  15. import android.annotation.SuppressLint;
  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.Environment;
  22. import android.os.Looper;
  23. import android.os.SystemClock;
  24. import android.util.Log;
  25. import android.widget.Toast;
  26.  
  27. import com.wlwl.common.Config;
  28.  
  29. import com.wlwl.tools.FileX;
  30. import com.wlwl.tools.URLX;
  31. import com.wlwl.tools.UtilX;
  32.  
  33. @SuppressLint("SimpleDateFormat")
  34. public class CrashHandler implements UncaughtExceptionHandler {
  35.  
  36. public static String TAG = "MyCrash";
  37. // 系统默认的UncaughtException处理类
  38. private Thread.UncaughtExceptionHandler mDefaultHandler;
  39.  
  40. private static CrashHandler instance = new CrashHandler();
  41. private Context mContext;
  42.  
  43. // 用来存储设备信息和异常信息
  44. private Map<String, String> infos = new HashMap<String, String>();
  45.  
  46. // 用于格式化日期,作为日志文件名的一部分
  47. private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
  48.  
  49. /** 保证只有一个CrashHandler实例 */
  50. private CrashHandler() {
  51. }
  52.  
  53. /** 获取CrashHandler实例 ,单例模式 */
  54. public static CrashHandler getInstance() {
  55. return instance;
  56. }
  57.  
  58. /**
  59. * 初始化
  60. *
  61. * @param context
  62. */
  63. public void init(Context context) {
  64. mContext = context;
  65. // 获取系统默认的UncaughtException处理器
  66. mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  67. // 设置该CrashHandler为程序的默认处理器
  68. Thread.setDefaultUncaughtExceptionHandler(this);
  69. autoClear(5);
  70. }
  71.  
  72. /**
  73. * 当UncaughtException发生时会转入该函数来处理
  74. */
  75. @Override
  76. public void uncaughtException(Thread thread, Throwable ex) {
  77. if (!handleException(ex) && mDefaultHandler != null) {
  78. // 如果用户没有处理则让系统默认的异常处理器来处理
  79. mDefaultHandler.uncaughtException(thread, ex);
  80. } else {
  81. SystemClock.sleep(3000);
  82. // 退出程序
  83. android.os.Process.killProcess(android.os.Process.myPid());
  84. System.exit(1);
  85. }
  86. }
  87.  
  88. /**
  89. * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  90. *
  91. * @param ex
  92. * @return true:如果处理了该异常信息; 否则返回false.
  93. */
  94. private boolean handleException(Throwable ex) {
  95. if (ex == null)
  96. return false;
  97.  
  98. try {
  99. // 使用Toast来显示异常信息
  100. new Thread() {
  101.  
  102. @Override
  103. public void run() {
  104. Looper.prepare();
  105. Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.",
  106. Toast.LENGTH_LONG).show();
  107. Looper.loop();
  108. }
  109. }.start();
  110. // 收集设备参数信息
  111. collectDeviceInfo(mContext);
  112. // 保存日志文件
  113. saveCrashInfoFile(ex);
  114. SystemClock.sleep(3000);
  115. } catch (Exception e) {
  116. e.printStackTrace();
  117. }
  118.  
  119. return true;
  120. }
  121.  
  122. /**
  123. * 收集设备参数信息
  124. *
  125. * @param ctx
  126. */
  127. public void collectDeviceInfo(Context ctx) {
  128. try {
  129. PackageManager pm = ctx.getPackageManager();
  130. PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
  131. PackageManager.GET_ACTIVITIES);
  132. if (pi != null) {
  133. String versionName = pi.versionName + "";
  134. String versionCode = pi.versionCode + "";
  135. infos.put("版本名称", versionName);
  136. infos.put("版本号", versionCode);
  137. }
  138. } catch (NameNotFoundException e) {
  139. Log.e(TAG, "an error occured when collect package info", e);
  140. }
  141. Field[] fields = Build.class.getDeclaredFields();
  142. for (Field field : fields) {
  143. try {
  144. field.setAccessible(true);
  145. infos.put(field.getName(), field.get(null).toString());
  146. } catch (Exception e) {
  147. Log.e(TAG, "an error occured when collect crash info", e);
  148. }
  149. }
  150. }
  151.  
  152. /**
  153. * 保存错误信息到文件中
  154. * @param ex
  155. * @return 返回文件名称,便于将文件传送到服务器
  156. * @throws Exception
  157. */
  158. private String saveCrashInfoFile(Throwable ex) throws Exception {
  159. StringBuffer sb = new StringBuffer();
  160. try {
  161. SimpleDateFormat sDateFormat = new SimpleDateFormat(
  162. "yyyy-MM-dd HH:mm:ss");
  163. String date = sDateFormat.format(new java.util.Date());
  164. sb.append("\r\n" + date + "\n");
  165. for (Map.Entry<String, String> entry : infos.entrySet()) {
  166. String key = entry.getKey();
  167. String value = entry.getValue();
  168. sb.append(key + "=" + value + "\n");
  169. }
  170.  
  171. Writer writer = new StringWriter();
  172. PrintWriter printWriter = new PrintWriter(writer);
  173. ex.printStackTrace(printWriter);
  174. Throwable cause = ex.getCause();
  175. while (cause != null) {
  176. cause.printStackTrace(printWriter);
  177. cause = cause.getCause();
  178. }
  179. printWriter.flush();
  180. printWriter.close();
  181. String result = writer.toString();
  182. sb.append(result);
  183.  
  184. String fileName = writeFile(sb.toString());
  185. return fileName;
  186. } catch (Exception e) {
  187. Log.e(TAG, "an error occured while writing file...", e);
  188. sb.append("an error occured while writing file...\r\n");
  189. writeFile(sb.toString());
  190. }
  191. return null;
  192. }
  193.  
  194. private String writeFile(String sb) throws Exception {
  195. String time = formatter.format(new Date());
  196. String fileName = "crash-" + time + "";
  197.  
  198. FileX.Write_Log(sb.toString(),true,fileName); //保存日志
  199.  
  200. int verCode = UtilX.getVerCode(mContext);
  201. String verName = UtilX.getVerName(mContext);
  202.  
  203. String QueryStringName = "?action=seterror";
  204.  
  205. Map<String,String> params = new HashMap<String,String>();
  206. params.put("error", sb.toString());
  207. params.put("verCode", verCode+"");
  208. params.put("verName", verName.toString());
  209.  
  210. String Url = Config.URL_SetPhone + QueryStringName;
  211. Log.i("SetError URL ", Url);
  212. String aaa = URLX.submitPostData(Url, params, "utf-8");
  213. Log.i("SetError", aaa);
  214.  
  215. return fileName;
  216. }
  217.  
  218. public static String getGlobalpath() {
  219. return Environment.getExternalStorageDirectory().getAbsolutePath()
  220. + File.separator + "crash" + File.separator;
  221. }
  222.  
  223. public static void setTag(String tag) {
  224. TAG = tag;
  225. }
  226.  
  227. /**
  228. * 文件删除
  229. * @param day 文件保存天数
  230. */
  231. public void autoClear(final int autoClearDay) {
  232. // FileUtil.delete(getGlobalpath(), new FilenameFilter() {
  233. //
  234. // @Override
  235. // public boolean accept(File file, String filename) {
  236. // String s = FileUtil.getFileNameWithoutExtension(filename);
  237. // int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay;
  238. // String date = "crash-" + DateUtil.getOtherDay(day);
  239. // return date.compareTo(s) >= 0;
  240. // }
  241. // });
  242.  
  243. }
  244.  
  245. }

  

  1. package com.wlwl.yiyuan;
  2.  
  3. import com.baidu.mapapi.SDKInitializer;
  4.  
  5. import com.wlwl.tools.LocationService;
  6.  
  7. import cn.jpush.android.api.JPushInterface;
  8. import android.app.Application;
  9. import android.app.Service;
  10. import android.os.Vibrator;
  11. import android.util.Log;
  12.  
  13. /**
  14. * For developer startup JPush SDK
  15. *
  16. * 一般建议在自定义 Application 类里初始化。也可以在主 Activity 里。
  17. */
  18. public class MyApplication extends Application {
  19.  
  20. private static final String TAG = "JPush";
  21. public LocationService locationService;
  22. public Vibrator mVibrator;
  23. @Override
  24. public void onCreate() {
  25.  
  26. super.onCreate();
  27.  
  28. try {
  29. JPushInterface.setDebugMode(true); // 设置开启日志,发布时请关闭日志
  30. JPushInterface.init(this); // 初始化 JPush
  31.  
  32. locationService = new LocationService(getApplicationContext());
  33. mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE);
  34.  
  35. CrashHandler.getInstance().init(this); //全局错误捕捉
  36.  
  37. } catch (Exception e) {
  38. // TODO: handle exception
  39. }
  40.  
  41. }
  42. }

  

Android 全局错误管理的更多相关文章

  1. android 进程/线程管理(一)----消息机制的框架

    一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...

  2. Android 之 内存管理-查看内存泄露(三)

    概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...

  3. 深入浅出 - Android系统移植与平台开发(十三)- Android的对象管理

    第六章.Android的对象管理 在Java中,不再使用的对象会通过gc机制来自己主动回收.而Android系统执行时库层代码是由C++编写的,在C++中创建的对象通常使用指针来操作,一旦使用不当.轻 ...

  4. Android系统如何管理自己内存的?

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 机缘巧合写下这篇博客,作为个人工作经验的总结,不足之处,随后补上. 安卓是基于Linux2.6内核的 ...

  5. 从零开始山寨Caffe·叁:全局线程管理器

    你需要一个管家,随手召唤的那种,想吃啥就吃啥. ——设计一个全局线程管理器 一个机器学习系统,需要管理一些公共的配置信息,如何存储这些配置信息,是一个难题. 设计模式 MVC框架 在传统的MVC编程框 ...

  6. Android TelephonyManager电话管理器

    今天介绍一下Android的电话管理器--TelephonyManager,TelephonyManager管理手机通话状态.电话网络信息的服务类,获取TelephonyManager: Teleph ...

  7. android 进程/线程管理(二)----关于线程的迷思

    一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...

  8. android 进程/线程管理(三)----Thread,Looper / HandlerThread / IntentService

    Thread,Looper的组合是非常常见的组合方式. Looper可以是和线程绑定的,或者是main looper的一个引用. 下面看看具体app层的使用. 首先定义thread: package ...

  9. android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)

    继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) ...

随机推荐

  1. jquery倾斜的动画导航菜单

    1. [代码]完整源代码  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  2. Python习题-登录

    写一个登录的程序,失败次数最多为3次,输入账号.密码错误,提示账号/密码错误.失败三次程序退出,输入正确,提示欢迎xxx登录 i=0while (i<3): username = input(' ...

  3. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  4. BZOJ5442: [Ceoi2018]Global warming

    BZOJ5442: [Ceoi2018]Global warming https://lydsy.com/JudgeOnline/problem.php?id=5442 分析: 等价于后缀加(前缀减也 ...

  5. ACM学习历程—HDU5407 CRB and Candies(数论)

    Problem Description CRB has N different candies. He is going to eat K candies.He wonders how many co ...

  6. oracle 12c 列式存储 ( In Memory 理论)

    随着Oracle 12c推出了in memory组件,使得Oracle数据库具有了双模式数据存放方式,从而能够实现对混合类型应用的支持:传统的以行形式保存的数据满足OLTP应用:列形式保存的数据满足以 ...

  7. C#SqlDataReader的用法

    string sqljn = "select [序号],[品名],[电压等级],[单位],[型号],[规格],[红本价格] FROM [book].[dbo].[View_wjprice]& ...

  8. poj 2105 IP Address(水题)

    一.Description Suppose you are reading byte streams from any device, representing IP addresses. Your ...

  9. java代码Math.sqrt

    总结:这个判断小数的题目,当时全只2有一个人想出了结果.老师很开心.我很桑心~~~~ 我没想到要取膜,我只想到了除以等于0就够了.至于中间的“取膜”,我没凑齐来,还是不够灵活 package com. ...

  10. java代码JFrame练习

    总结: package com.da; import java.awt.Button; import java.awt.Color; import java.awt.FlowLayout; impor ...