Android 全局错误管理
- package com.wlwl.yiyuan;
- import java.io.File;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.io.Writer;
- import java.lang.Thread.UncaughtExceptionHandler;
- import java.lang.reflect.Field;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.content.pm.PackageInfo;
- import android.content.pm.PackageManager;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.os.Build;
- import android.os.Environment;
- import android.os.Looper;
- import android.os.SystemClock;
- import android.util.Log;
- import android.widget.Toast;
- import com.wlwl.common.Config;
- import com.wlwl.tools.FileX;
- import com.wlwl.tools.URLX;
- import com.wlwl.tools.UtilX;
- @SuppressLint("SimpleDateFormat")
- public class CrashHandler implements UncaughtExceptionHandler {
- public static String TAG = "MyCrash";
- // 系统默认的UncaughtException处理类
- private Thread.UncaughtExceptionHandler mDefaultHandler;
- private static CrashHandler instance = new CrashHandler();
- private Context mContext;
- // 用来存储设备信息和异常信息
- private Map<String, String> infos = new HashMap<String, String>();
- // 用于格式化日期,作为日志文件名的一部分
- private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
- /** 保证只有一个CrashHandler实例 */
- private CrashHandler() {
- }
- /** 获取CrashHandler实例 ,单例模式 */
- public static CrashHandler getInstance() {
- return instance;
- }
- /**
- * 初始化
- *
- * @param context
- */
- public void init(Context context) {
- mContext = context;
- // 获取系统默认的UncaughtException处理器
- mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
- // 设置该CrashHandler为程序的默认处理器
- Thread.setDefaultUncaughtExceptionHandler(this);
- autoClear(5);
- }
- /**
- * 当UncaughtException发生时会转入该函数来处理
- */
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- if (!handleException(ex) && mDefaultHandler != null) {
- // 如果用户没有处理则让系统默认的异常处理器来处理
- mDefaultHandler.uncaughtException(thread, ex);
- } else {
- SystemClock.sleep(3000);
- // 退出程序
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(1);
- }
- }
- /**
- * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
- *
- * @param ex
- * @return true:如果处理了该异常信息; 否则返回false.
- */
- private boolean handleException(Throwable ex) {
- if (ex == null)
- return false;
- try {
- // 使用Toast来显示异常信息
- new Thread() {
- @Override
- public void run() {
- Looper.prepare();
- Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.",
- Toast.LENGTH_LONG).show();
- Looper.loop();
- }
- }.start();
- // 收集设备参数信息
- collectDeviceInfo(mContext);
- // 保存日志文件
- saveCrashInfoFile(ex);
- SystemClock.sleep(3000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return true;
- }
- /**
- * 收集设备参数信息
- *
- * @param ctx
- */
- public void collectDeviceInfo(Context ctx) {
- try {
- PackageManager pm = ctx.getPackageManager();
- PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
- PackageManager.GET_ACTIVITIES);
- if (pi != null) {
- String versionName = pi.versionName + "";
- String versionCode = pi.versionCode + "";
- infos.put("版本名称", versionName);
- infos.put("版本号", versionCode);
- }
- } catch (NameNotFoundException e) {
- Log.e(TAG, "an error occured when collect package info", e);
- }
- Field[] fields = Build.class.getDeclaredFields();
- for (Field field : fields) {
- try {
- field.setAccessible(true);
- infos.put(field.getName(), field.get(null).toString());
- } catch (Exception e) {
- Log.e(TAG, "an error occured when collect crash info", e);
- }
- }
- }
- /**
- * 保存错误信息到文件中
- * @param ex
- * @return 返回文件名称,便于将文件传送到服务器
- * @throws Exception
- */
- private String saveCrashInfoFile(Throwable ex) throws Exception {
- StringBuffer sb = new StringBuffer();
- try {
- SimpleDateFormat sDateFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH:mm:ss");
- String date = sDateFormat.format(new java.util.Date());
- sb.append("\r\n" + date + "\n");
- for (Map.Entry<String, String> entry : infos.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- sb.append(key + "=" + value + "\n");
- }
- Writer writer = new StringWriter();
- PrintWriter printWriter = new PrintWriter(writer);
- ex.printStackTrace(printWriter);
- Throwable cause = ex.getCause();
- while (cause != null) {
- cause.printStackTrace(printWriter);
- cause = cause.getCause();
- }
- printWriter.flush();
- printWriter.close();
- String result = writer.toString();
- sb.append(result);
- String fileName = writeFile(sb.toString());
- return fileName;
- } catch (Exception e) {
- Log.e(TAG, "an error occured while writing file...", e);
- sb.append("an error occured while writing file...\r\n");
- writeFile(sb.toString());
- }
- return null;
- }
- private String writeFile(String sb) throws Exception {
- String time = formatter.format(new Date());
- String fileName = "crash-" + time + "";
- FileX.Write_Log(sb.toString(),true,fileName); //保存日志
- int verCode = UtilX.getVerCode(mContext);
- String verName = UtilX.getVerName(mContext);
- String QueryStringName = "?action=seterror";
- Map<String,String> params = new HashMap<String,String>();
- params.put("error", sb.toString());
- params.put("verCode", verCode+"");
- params.put("verName", verName.toString());
- String Url = Config.URL_SetPhone + QueryStringName;
- Log.i("SetError URL ", Url);
- String aaa = URLX.submitPostData(Url, params, "utf-8");
- Log.i("SetError", aaa);
- return fileName;
- }
- public static String getGlobalpath() {
- return Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + "crash" + File.separator;
- }
- public static void setTag(String tag) {
- TAG = tag;
- }
- /**
- * 文件删除
- * @param day 文件保存天数
- */
- public void autoClear(final int autoClearDay) {
- // FileUtil.delete(getGlobalpath(), new FilenameFilter() {
- //
- // @Override
- // public boolean accept(File file, String filename) {
- // String s = FileUtil.getFileNameWithoutExtension(filename);
- // int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay;
- // String date = "crash-" + DateUtil.getOtherDay(day);
- // return date.compareTo(s) >= 0;
- // }
- // });
- }
- }
- package com.wlwl.yiyuan;
- import com.baidu.mapapi.SDKInitializer;
- import com.wlwl.tools.LocationService;
- import cn.jpush.android.api.JPushInterface;
- import android.app.Application;
- import android.app.Service;
- import android.os.Vibrator;
- import android.util.Log;
- /**
- * For developer startup JPush SDK
- *
- * 一般建议在自定义 Application 类里初始化。也可以在主 Activity 里。
- */
- public class MyApplication extends Application {
- private static final String TAG = "JPush";
- public LocationService locationService;
- public Vibrator mVibrator;
- @Override
- public void onCreate() {
- super.onCreate();
- try {
- JPushInterface.setDebugMode(true); // 设置开启日志,发布时请关闭日志
- JPushInterface.init(this); // 初始化 JPush
- locationService = new LocationService(getApplicationContext());
- mVibrator =(Vibrator)getApplicationContext().getSystemService(Service.VIBRATOR_SERVICE);
- CrashHandler.getInstance().init(this); //全局错误捕捉
- } catch (Exception e) {
- // TODO: handle exception
- }
- }
- }
Android 全局错误管理的更多相关文章
- android 进程/线程管理(一)----消息机制的框架
一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...
- Android 之 内存管理-查看内存泄露(三)
概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...
- 深入浅出 - Android系统移植与平台开发(十三)- Android的对象管理
第六章.Android的对象管理 在Java中,不再使用的对象会通过gc机制来自己主动回收.而Android系统执行时库层代码是由C++编写的,在C++中创建的对象通常使用指针来操作,一旦使用不当.轻 ...
- Android系统如何管理自己内存的?
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 机缘巧合写下这篇博客,作为个人工作经验的总结,不足之处,随后补上. 安卓是基于Linux2.6内核的 ...
- 从零开始山寨Caffe·叁:全局线程管理器
你需要一个管家,随手召唤的那种,想吃啥就吃啥. ——设计一个全局线程管理器 一个机器学习系统,需要管理一些公共的配置信息,如何存储这些配置信息,是一个难题. 设计模式 MVC框架 在传统的MVC编程框 ...
- Android TelephonyManager电话管理器
今天介绍一下Android的电话管理器--TelephonyManager,TelephonyManager管理手机通话状态.电话网络信息的服务类,获取TelephonyManager: Teleph ...
- android 进程/线程管理(二)----关于线程的迷思
一:进程和线程的由来 进程是计算机科技发展的过程的产物. 最早计算机发明出来,是为了解决数学计算而发明的.每解决一个问题,就要打纸带,也就是打点. 后来人们发现可以批量的设置命令,由计算机读取这些命令 ...
- android 进程/线程管理(三)----Thread,Looper / HandlerThread / IntentService
Thread,Looper的组合是非常常见的组合方式. Looper可以是和线程绑定的,或者是main looper的一个引用. 下面看看具体app层的使用. 首先定义thread: package ...
- android 进程/线程管理(四)续----消息机制的思考(自定义消息机制)
继续分析handler 和looper 先看看handler的 public void dispatchMessage(Message msg) { if (msg.callback != null) ...
随机推荐
- jquery倾斜的动画导航菜单
1. [代码]完整源代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...
- Python习题-登录
写一个登录的程序,失败次数最多为3次,输入账号.密码错误,提示账号/密码错误.失败三次程序退出,输入正确,提示欢迎xxx登录 i=0while (i<3): username = input(' ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- BZOJ5442: [Ceoi2018]Global warming
BZOJ5442: [Ceoi2018]Global warming https://lydsy.com/JudgeOnline/problem.php?id=5442 分析: 等价于后缀加(前缀减也 ...
- ACM学习历程—HDU5407 CRB and Candies(数论)
Problem Description CRB has N different candies. He is going to eat K candies.He wonders how many co ...
- oracle 12c 列式存储 ( In Memory 理论)
随着Oracle 12c推出了in memory组件,使得Oracle数据库具有了双模式数据存放方式,从而能够实现对混合类型应用的支持:传统的以行形式保存的数据满足OLTP应用:列形式保存的数据满足以 ...
- C#SqlDataReader的用法
string sqljn = "select [序号],[品名],[电压等级],[单位],[型号],[规格],[红本价格] FROM [book].[dbo].[View_wjprice]& ...
- poj 2105 IP Address(水题)
一.Description Suppose you are reading byte streams from any device, representing IP addresses. Your ...
- java代码Math.sqrt
总结:这个判断小数的题目,当时全只2有一个人想出了结果.老师很开心.我很桑心~~~~ 我没想到要取膜,我只想到了除以等于0就够了.至于中间的“取膜”,我没凑齐来,还是不够灵活 package com. ...
- java代码JFrame练习
总结: package com.da; import java.awt.Button; import java.awt.Color; import java.awt.FlowLayout; impor ...