Android CrashHandler全局异常

CrashHandler 介绍

Android 应用不可避免的会发生crash 即崩溃,无论程序写的多好,都会不可避免的发生崩溃,可能是由底层引起的,也有可能是写的代码引起的。当crash发生时,系统会kill掉正在执行的程序,现象是程序闪退或提升用户已停止运行。出现这种情况,开发者却无法得到程序为何crash。Android 提供了处理这类问题的方法。
java的Thread中有一个UncaughtExceptionHandler接口,该接口的作用主要是为 了 当 Thread 因未捕获的异常而突然终止时,调用处理程序。

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {// Android-removed: SecurityManager stubbed out on Android./*SecurityManager sm = System.getSecurityManager();if (sm != null) {sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler"));}*/defaultUncaughtExceptionHandler = eh;}public interface UncaughtExceptionHandler {/*** Method invoked when the given thread terminates due to the* given uncaught exception.* <p>Any exception thrown by this method will be ignored by the* Java Virtual Machine.* @param t the thread* @param e the exception*/void uncaughtException(Thread t, Throwable e);}

使用


public class CrashHandler implements Thread.UncaughtExceptionHandler {public static final String TAG = "CrashHandler";private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/Crash/log";private static final String FILE_NAME = "crash";private static final String FILE_NAME_SUFFIX = ".trace";private static CrashHandler mInstance;private Context mContext;private Thread.UncaughtExceptionHandler mDefaultCrashHandler;public CrashHandler() {}public static synchronized CrashHandler getInstance() {if (mInstance == null) {synchronized (CrashHandler.class) {if (mInstance == null) {mInstance = new CrashHandler();}}}return mInstance;}public void init(Context context) {mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(this);mContext = context.getApplicationContext();}/*** 当程序中有未被捕获的异常,系统将会自动调用uncaughtException方法** @param thread 为出现未捕获异常的线程* @param ex     为未捕获的异常*/@Overridepublic void uncaughtException(@NonNull Thread thread, @NonNull Throwable ex) {try {//导出异常信息到SDCard中dumpExceptionToSDCard(ex);uploadExceptionToServer();} catch (IOException e) {e.printStackTrace();}ex.printStackTrace();//如果系统提供了默认异常处理器,则交给系统去结束程序,否则就由自己结束自己if (mDefaultCrashHandler != null) {mDefaultCrashHandler.uncaughtException(thread, ex);} else {Process.killProcess(Process.myPid());}}private void dumpExceptionToSDCard(Throwable ex) throws IOException {//判断SD是否存在if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判断是否是DebugLog.w(TAG, "sdcard unmounted dump exception");return;}File dir = new File(PATH);if (!dir.exists()) {dir.mkdirs();}long currentTimeMillis = System.currentTimeMillis();String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(currentTimeMillis);File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);Log.i(TAG, "fileName:" + file.getName() + " , path:" + file.getPath());try {PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));printWriter.println(time);dumpPhoneInfo(printWriter);printWriter.println();ex.printStackTrace(printWriter);printWriter.close();} catch (Exception e) {Log.e(TAG, "dump crash info failed");e.printStackTrace();}}private void dumpPhoneInfo(PrintWriter printWriter) throws PackageManager.NameNotFoundException {PackageManager pm = mContext.getPackageManager();PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);printWriter.print("App Version: ");printWriter.print(pi.versionName);printWriter.print("_");printWriter.println(pi.versionCode);//Android 版本号printWriter.print("OS Version: ");printWriter.print(Build.VERSION.RELEASE);printWriter.print("_");printWriter.println(Build.VERSION.SDK_INT);//手机制造商printWriter.print("Vendor: ");printWriter.println(Build.MANUFACTURER);//手机型号printWriter.print("Model: ");printWriter.println(Build.MODEL);//CPU架构printWriter.print("CPU ABI: ");printWriter.println(Build.CPU_ABI);}private void uploadExceptionToServer() {// TODO upload Exception Message To Your Server}
}

在Applicaption 类中初始化

public class TestApplication extends Application {@Overridepublic void onCreate() {super.onCreate();context = getApplicationContext();CrashHandler instance = CrashHandler.getInstance();instance.init(this);}
}

自己手动抛出一个异常

        addDisposable(RxView.clicks(mainBinding.settingIv).throttleFirst(PDAConstant.CLICK, TimeUnit.SECONDS).subscribe(o -> {throw new RuntimeException(" 自定义 exception");}));

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/9393.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redhat7.6安装mysql5.7

环境准备&#xff1a;硬盘剩余空间最少8G,内存剩余最少2G Mysql官网下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.html 在Mysql官网下载列表中选择需要安装的版本: RedHat7.6安装MySQL5.7 安装之前&#xff0c;先要保证系统环境是干净的&#xff0c;不能存…

Docker网络管理应用

实验要求 了解Docker常用网络模式&#xff0c;掌握Docker常用网络模式的使用。主要任务是利用busybox镜像建立容器&#xff0c;容器名称为test_busybox1和test_busybox2&#xff0c;将网络模式设置为none&#xff0c;并为容器配置IP地址&#xff0c;容器test_busybox1的IP设置…

搜索二叉树

目录&#xff1a; 1.搜索二叉树的概念 2.对搜索二叉树实现插入Insert函数和InOrder中序遍历函数 3.删除 4.实现搜索二叉树的递归 5.拷贝问题 6.搜索二叉树的缺陷 ---------------------------------------------------------------------------------------------------------…

Python Websocket 控制大屏显示

场景描述&#xff1a; 在做大屏展示时&#xff0c;有这样一个需求&#xff1a;在不刷新页面的情况下&#xff0c;动态改变大屏展示内容&#xff0c;如&#xff1a;执行某个函数&#xff0c;把相关数据醒目展示&#xff0c;轮换数据显示顺序等等。比如有领导参观时&#xff0c;马…

通过阿里云函数计算FC实现音视频转码

1.进入阿里云函数计算FC页面 2.创建音视频转码应用 可以看到代码&#xff0c;看到相关的传参 3.进行测试 编辑测试参数&#xff0c;使用账号的OSS中的资源 点击测试函数进行测试 可以在OSS中看到生成的mp4格式的视频了 测试后发现函数计算可以使用 4. 接下来就是在项目中通过代…

logback日志的分片压缩

logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration debug"true"><springProperty name"LOG_PATH" source"shands.log.logPath" defaultValue"/var/delonix/logs/local"…

el-date-picker禁用指定日期之前或之后的日期

一、elementUI中el-date-picker禁用指定日期之前或之后的日期 通过配置picker-options配置指定禁用日期&#xff08;pickerOptions写到data里面&#xff09; <el-date-pickerv-model"date"type"date"size"small"value-format"yyyy-MM-d…

基于matlab使用视频和深度学习进行手势识别(附源码)

一、前言 此示例首先演示如何使用预训练的SlowFast视频分类器执行手势识别&#xff0c;然后演示如何使用迁移学习在自定义手势识别数据集上训练分类器。 基于视觉的人类手势识别涉及使用一组视频帧预测手势&#xff0c;例如挥手打招呼、手语手势或鼓掌。手势识别的一个吸引人…

【VSCODE】4、vscode git pull/push 报错 remote: HTTP Basic: Access denied

一、报错示例 在执行 git pull/push 的时候报错如下 二、解决方式 该问题来自 vscode 的身份验证 打开 vscode →code → 首选项 → 设置搜索 git.terminalAuthentication取消选中该选项重启终端即可

5.8.5 TCP可靠传输(一)序号确认机制

5.8.5 TCP可靠传输&#xff08;一&#xff09;序号确认机制 TCP是可靠的传输层协议&#xff0c;主要通过序号确认机制、超时重传机制、定时器三个方面实现可靠传输。 一、序号确认机制 TCP将所要传送的整个的应用层报文看成是一个一个字节组成的数据流&#xff0c;并对每一个…

sql统计某一字段不同状态的数量,时间戳转日期格式、按月统计使用

背景 1、在sql语句中统计一个字段的不同状态时&#xff0c;需要将每个状态的数量查出来&#xff0c;在进行统一输出&#xff0c;涉及表多次查询&#xff0c;下面用一个聚合函数的方式进行查询&#xff0c;比较方便&#xff0c;容易理解。 2、有时候数据表中的时间字段存储的是…

Jmeter使用之:怎么编写扩展函数(二)

目录 前言&#xff1a; 1、实现function的类的package声明必须包含".functions" 2、需要继承org.apache.jmeter.functions.AbstractFunction&#xff0c;并且实现相应的方法。 第一步&#xff1a;eclipse 导入jmeter目录&#xff1a;apache-jmeter-2.13libext下的…