public class CrashHandler implements UncaughtExceptionHandler
{
private static CrashHandler instance;
public static final String TAG = "CrashHandler";
private static final String VERSION_NAME = "versionName";
private static final String VERSION_CODE = "versionCode";
private static final String STACK_TRACE = "STACK_TRACE";
private Thread.UncaughtExceptionHandler mDefaultHandler;
private Context mContext;
private static final String CRASH_REPORTER_EXTENSION = ".cr";
private Properties deviceCrashInfo = new Properties();
private CrashHandler()
{
}
public static synchronized CrashHandler getInstance()
{
if (instance == null)
{
instance = new CrashHandler();
}
return instance;
}
public void init(Context ctx)
{
this.mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
if (mDefaultHandler != null && !handlerException(ex))
{
// 如果用户没有进行异常处理就让系统默认的处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else
{
exitApp();
}
}
private boolean handlerException(Throwable ex)
{
if (ex == null)
{
return true;
}
final String msg = ex.getLocalizedMessage();
new Thread() {
@Override
public void run()
{
Looper.prepare();
Toast toast = Toast.makeText(mContext, "程序出错啦!" + msg, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
Looper.loop();
}
}.start();
// 收集设备信息
collectDeviceInfo(mContext);
// 保存错误
saveCrashInfoToFiles(ex);
// 发送错误报告到服务器
sendCrashReportsToServer(mContext);
return true;
}
private void collectDeviceInfo(Context ctx)
{
try
{
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageArchiveInfo(ctx.getPackageName(),
PackageManager.GET_ACTIVITIES);
if (pi != null)
{
deviceCrashInfo.put(VERSION_NAME, pi.versionName == null ? "not set"
: pi.versionName);
deviceCrashInfo.put(VERSION_CODE, pi.versionCode);
}
} catch (Exception e)
{
Log.e(TAG, "error occured when collecting crash info" + e);
}
// 使用反射来收集设备信息.在Build类中包含各种设备信息,
// 例如: 系统版本号,设备生产商 等帮助调试程序的有用信息
// 具体信息请参考后面的截图
Field[] fields = Builder.class.getDeclaredFields();
for (Field field : fields)
{
try
{
field.setAccessible(true);
deviceCrashInfo.put(field.getName(), null);
} catch (Exception e)
{
Log.e(TAG, "error occured when collecting device info" + e);
}
}
}
private String saveCrashInfoToFiles(Throwable ex)
{
Writer info = new StringWriter();
PrintWriter printWriter = new PrintWriter(info);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null)
{
ex.printStackTrace(printWriter);
cause = cause.getCause();
}
String result = info.toString();
printWriter.close();
deviceCrashInfo.put("EXCEPTION", ex.getLocalizedMessage());
deviceCrashInfo.put(STACK_TRACE, result);
try
{
long time = System.currentTimeMillis();
String filename = "crash-" + time + CRASH_REPORTER_EXTENSION;
FileOutputStream trace = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
deviceCrashInfo.store(trace, "");
trace.flush();
trace.close();
} catch (Exception e)
{
Log.e(TAG, "error occured when save crashinfo to files" + e);
}
return null;
}
private void sendCrashReportsToServer(Context ctx)
{
String[] crFiles = getCrashReportFiles(ctx);
if (crFiles != null && crFiles.length > 0)
{
TreeSet<String> sortedFiles = new TreeSet<String>();
sortedFiles.addAll(Arrays.asList(crFiles));
for (String fileName : sortedFiles)
{
File cr = new File(ctx.getFilesDir(), fileName);
postReport(cr);
cr.delete();// 删除已发送的报告
}
}
}
private void postReport(File file)
{
// TODO 发送错误报告到服务器
}
private String[] getCrashReportFiles(Context ctx)
{
File filesDir = ctx.getFilesDir();
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name)
{
return name.endsWith(CRASH_REPORTER_EXTENSION);
}
};
return filesDir.list(filter);
}
private void exitApp()
{
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}
结伴旅游网,一个免费的交友网站:www.jieberu.com
推推族,免费得门票,游景区:www.tuituizu.com
- Xamarin.Android-捕获未处理异常(全局异常)
一.前言 android中如果出现了未处理的异常,程序会闪退,这是非常不好的用户体验,很多用户会因此卸载APP,因此未处理的异常是应该尽力避免的. 有些很难避免的异常(如:IO.网络等),应在代码中进 ...
- springmvc处理局部异常和全局异常
springmvc通过HandlerExceptionResolver(是一个接口,在spring-webmvc依赖下)处理程序异常,包括处理器异常.数据绑定异常以及处理器执行时发生的异常.Handl ...
- Application中捕获APP中的全局异常
package com.example.administrator.mystudent; import android.app.Application; import android.util.Log ...
- 如何捕获Wince下form程序的全局异常
前言 上两篇文章我们总结了在winform程序下如何捕获全局的异常.那么同样的问题,在wince下我们如何来处理呢?用相同的代码来处理可以吗? 答案是否定的,上面的方案1完全不能解决wince下的情况 ...
- 从壹开始前后端分离 [.netCore 不定期更新 ] 三十五║ 完美实现全局异常日志记录
缘起 哈喽我是不定期更新的日常,昨天群里小伙伴问到了记录日志,当然,以前我也挖过这个坑,后来一直没有来得及填上,也想着 swagger 一直又有错误信息展示的功能,就迟迟没有添加这个功能,不过昨天夜里 ...
- Asp.net Core全局异常监控和记录日志
前言 系统异常监控可以说是重中之重,系统不可能一直运行良好,开发和运维也不可能24小时盯着系统,系统抛异常后我们应当在第一时间收到异常信息.在Asp.net Core里我使用拦截器 ...
- 【spring】-- springboot配置全局异常处理器
一.为什么要使用全局异常处理器? 什么是全局异常处理器? 就是把错误异常统一处理的方法. 应用场景: 1.当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句 ...
- SprimgMVC学习笔记(六)—— 全局异常的处理
一.处理思路 springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 系统中异常包括两类:预期异常和运行时异常RuntimeExcept ...
- 【转】 Android自定义捕获Application全局异常
大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...
随机推荐
- hive_server2的权限控制
CDH的core-sit开启: 第一个false表示用系统用户来和hive用户的权限绑定,但经测试并没有生效,所以可以改为true 第二项设置成ALL,表示创建者对其创建的表拥有所有的权限,这样也是比 ...
- Spring中pom文件所需节点
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> &l ...
- 【6.18校内test】T3细胞分裂
尽管T1T2很简单,但还是阻止不了我T3wa一片 细胞分裂[题目链接] xcg同学有一个80pts的代码 他说他的代码和我的很像,可惜我比较笨,只有30pts 其实这道题考场上是想到要分解质因数了,然 ...
- centos 6.x 编译安装 pgsql 9.6
文章结构如下: 一. 环境配置 1. 配置防火墙 查看IPTABLES 当前状态与关闭过程 chkconfig --list|grep iptables 关闭iptables service ipta ...
- sublime text 3 环境设置
1. 设置build system 环境 tool -> build system -> new build system ,粘贴以下代码并保存 { "cmd":[&q ...
- the server responsed width a status of 404 (Not Found)
最近使用VS code写代码,使用Beautify插件格式化代码后,报以下错误: 反复查看代码,初始感觉没什么问题,有点懵.. 随着时间的推移,后来果然发现问题所在: 在加载模块的地方,多出了个空格( ...
- 初探html-17 表单
HTML 表单和输入 HTML 表单用于收集不同类型的用户输入. 在线实例 <form action=""> First name: <input type=&q ...
- 安装wordpress的过程
1 首先安装lamp.在安装php时,由于ubuntu16.04源中自带的是php7,所以需要直接安装 apt-get install phpapt-get install libapache2-mo ...
- [转]实际项目中如何使用Git做分支管理 (A successful Git branching model)
来自 https://nvie.com/posts/a-successful-git-branching-model/ In this post I present the development m ...
- mariadb主从架构
mariadb主从架构(异步)和集群 一般应用的场所是网站,主的机器是可以写可以读,从的机器可以读,也可以写,但不会同步.只有主的机器增删改,从的机器才会同步. 主从至少三个线程:dump.I/O t ...