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系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...
随机推荐
- XOR on segment(线段树区间异或更新)
原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...
- 数组遍历方法forEach 和 map 的区别
数组遍历方法forEach 和 map 的区别:https://www.cnblogs.com/sticktong/p/7602783.html
- Head First PHP&MySQl第四章代码
addemail.php <!DOCTYPE html> <html lang="cn" dir="ltr"> <head> ...
- laravel5.5学习2-路由系统
一.初识路由 路由系统是所有 PHP 框架的核心,路由承载的是 URL 到代码片段的映射,不同的框架所附带的路由系统是这个框架本质最真实的写照,一丝不挂,一览无余.Laravel 路由中文文档:htt ...
- 微信小程序实现滑动删除效果
在一些app中,随处可见左滑动的效果,在微信小程序中,官方并未提供相关组件,需要我们自己动手写一个类似的效果 下面仅列举出核心代码,具体的优化需要根据你自身的需求 <view class='li ...
- uoj #450[集训队作业2018]复读机
传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...
- jquery判断 input type="file"上传文件是否为空
要想获取type="file"的input内容,用var file = $("id").val();肯定是不行的,下面是代码: html上传按钮为: <i ...
- css实现div水平垂直居中
中秋快到了,祝大家中秋快乐. 平时大家写bug过程中肯定会遇到让div框水平或者垂直居中,然而有时候能居中,有时候不能居中.我把平时遇到的一些方法写出来,如果对你有用,那便是晴天. 1.text-al ...
- 我所了解的https
http大家多少都有些了解,毕竟要上网的话是肯定会接触到它的.http有个很明显的缺点,就是传输是明文的,很不安全.针对这个情况,就推出了https,也就是http+ssl/tls. 对于明文不安全的 ...
- CSS布局方式
1.内边距 padding <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...