我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android崩溃异常捕获方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android崩溃异常捕获方法

开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。
那么今天主要讲一下如何去捕捉系统出现的Unchecked异常。何为Unchecked异常呢,换句话说就是指非受检异常,它不能用try-catch来显示捕捉。

我们先从Exception讲起。Exception分为两类:一种是CheckedException,一种是UncheckedException。这两种Exception的区别主要是CheckedException需要用try...catch...显示的捕获,而UncheckedException不需要捕获。通常UncheckedException又叫做RuntimeException。《effective java》指出:对于可恢复的条件使用被检查的异常(CheckedException),对于程序错误(言外之意不可恢复,大错已经酿成)使用运行时异常(RuntimeException)。我们常见的RuntimeExcepiton有IllegalArgumentException、IllegalStateException、NullPointerException、IndexOutOfBoundsException等等。对于那些CheckedException就不胜枚举了,我们在编写程序过程中try...catch...捕捉的异常都是CheckedException。io包中的IOException及其子类,这些都是CheckedException。

一、使用UncaughtExceptionHandler来捕获unchecked异常

UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告。
直接上代码吧


import java.io.File;
import java.io.FileOutputStream;
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.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.util.Log;
import android.widget.Toast;

@SuppressLint("SdCardPath")
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "TEST";
// CrashHandler 实例
private static CrashHandler INSTANCE = new CrashHandler();
// 程序的 Context 对象
private Context mContext;
// 系统默认的 UncaughtException 处理类
private Thread.UncaughtExceptionHandler mDefaultHandler;
// 用来存储设备信息和异常信息
private Map<String, String> infos = new HashMap<String, String>();
// 用来显示Toast中的信息
private static String error = "程序错误,额,不对,我应该说,服务器正在维护中,请稍后再试";
private static final Map<String, String> regexMap = new HashMap<String, String>();
// 用于格式化日期,作为日志文件名的一部分
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss",
Locale.CHINA);

private CrashHandler() {
//
}

public static CrashHandler getInstance() {
initMap();
return INSTANCE;
}

public void init(Context context) {
mContext = context;
// 获取系统默认的 UncaughtException 处理器
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// 设置该 CrashHandler 为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(this);
Log.d("TEST", "Crash:init");
}

@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
Log.d("TEST", "defalut");
} else {
try {
Thread.sleep();
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
}
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
// mDefaultHandler.uncaughtException(thread, ex);
System.exit();
}
}

private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
// 收集设备参数信息
// collectDeviceInfo(mContext);
// 保存日志文件
saveCrashInfoFile(ex);
// 使用 Toast 来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, error, Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
return true;
}

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 == null ? "null"
: pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", 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());
Log.d(TAG, field.getName() + " : " + field.get(null));
} catch (Exception e) {
Log.e(TAG, "an error occured when collect crash info", e);
}
}
}

private String saveCrashInfoFile(Throwable ex) {
StringBuffer sb = getTraceInfo(ex);
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.close();
String result = writer.toString();
sb.append(result);
try {
long timestamp = System.currentTimeMillis();
String time = formatter.format(new Date());
String fileName = "crash-" + time + "-" + timestamp + ".log";
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory()
+ "/crash/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
fos.close();
}
return fileName;
} catch (Exception e) {
Log.e(TAG, "an error occured while writing file...", e);
}
return null;
}

public static StringBuffer getTraceInfo(Throwable e) {
StringBuffer sb = new StringBuffer();
Throwable ex = e.getCause() == null ? e : e.getCause();
StackTraceElement[] stacks = ex.getStackTrace();
for (int i = ; i < stacks.length; i++) {
if (i == ) {
setError(ex.toString());
}
sb.append("class: ").append(stacks[i].getClassName())
.append("; method: ").append(stacks[i].getMethodName())
.append("; line: ").append(stacks[i].getLineNumber())
.append("; Exception: ").append(ex.toString() + "\n");
}
Log.d(TAG, sb.toString());
return sb;
}

public static void setError(String e) {
Pattern pattern;
Matcher matcher;
for (Entry<String, String> m : regexMap.entrySet()) {
Log.d(TAG, e+"key:" + m.getKey() + "; value:" + m.getValue());
pattern = Pattern.compile(m.getKey());
matcher = pattern.matcher(e);
if(matcher.matches()){
error = m.getValue();
break;
}
}
}

private static void initMap() {
// Java.lang.NullPointerException
// java.lang.ClassNotFoundException
// java.lang.ArithmeticException
// java.lang.ArrayIndexOutOfBoundsException
// java.lang.IllegalArgumentException
// java.lang.IllegalAccessException
// SecturityException
// NumberFormatException
// OutOfMemoryError 
// StackOverflowError 
// RuntimeException 
regexMap.put(".*NullPointerException.*", "嘿,无中生有~Boom!");
regexMap.put(".*ClassNotFoundException.*", "你确定你能找得到它?");
regexMap.put(".*ArithmeticException.*", "我猜你的数学是体育老师教的,对吧?");
regexMap.put(".*ArrayIndexOutOfBoundsException.*", "恩,无下限=无节操,请不要跟我搭话");
regexMap.put(".*IllegalArgumentException.*", "你的出生就是一场错误。");
regexMap.put(".*IllegalAccessException.*", "很遗憾,你的信用卡账号被冻结了,无权支付");
regexMap.put(".*SecturityException.*", "死神马上降临");
regexMap.put(".*NumberFormatException.*", "想要改变一下自己形象?去泰国吧,包你满意");
regexMap.put(".*OutOfMemoryError.*", "或许你该减减肥了");
regexMap.put(".*StackOverflowError.*", "啊,啊,憋不住了!");
regexMap.put(".*RuntimeException.*", "你的人生走错了方向,重来吧");
}
}

二、建立一个Application来全局监控


import android.app.Application;
public class CrashApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());
}
} 

最后在配置文件中加入注册信息


<application android:name=".CrashApplication" ... /> 

和权限


<!--uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

提交错误日志到网络服务器这一块还没有添加。如果添加了这一块功能,就能够实时的得要用户使用时的错误日志,能够及时反馈不同机型不同时候发生的错误,能对我们开发者的后期维护带来极大的方便。

有关Android崩溃异常捕获方法小编就给大家介绍这么多,希望对大家有所帮助!

您可能感兴趣的文章:Android跨进程抛异常的原理的实现android 捕获系统异常并上传日志具体实现Android 后台发送邮件示例 (收集应用异常信息+Demo代码)详解Android全局异常的捕获处理详解Android中处理崩溃异常Android 全局异常捕获实例详解解决Android平台中应用程序OOM异常的方法Android自定义抛出异常的方法详解


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android崩溃异常捕获方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android崩溃异常捕获方法

开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
Android崩溃异常捕获方法
2022-06-06

Java中未捕获或处理异常,导致程序崩溃或无法正常执行

本文将详细探讨未捕获或未处理异常的原因、影响和解决方法,并提供一些实用的建议。
Java程序2024-11-30

Android iOS常用APP崩溃日志获取命令方法

目录前言Android 崩溃日志获取方法iOS 崩溃日志获取方法前言 ​ 在日常的测试工作过程中,app可能会出现闪退崩溃的情况,这个时候就需要测试同学快速抓取到崩溃日志,来有效的辅助开发定位问题,快速的去解决问题。 分享Android &
Android iOS常用APP崩溃日志获取命令方法
2022-06-07

干货|安卓APP崩溃捕获方案——xCrash

导读2019 年,爱奇艺在 GitHub 上开源了 xCrash。这是一个比较完整的安卓 APP 崩溃捕获 SDK,它能在 App 进程崩溃时,在你指定的目录中生成 tombstone 文件(格式与系统的 tombstone 文件类似)。它
2023-06-05

详解Android中处理崩溃异常

大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开发者应该及时获取在该设备上导
2022-06-06

Android 记录未捕获异常

文章目录一、CrashHandler二、初始化三、测试四、打印 stackTrace 一、CrashHandler 自定义 Crash 处理器: object CrashHandler : Thread.UncaughtExceptionH
2022-06-06

python中异常捕获方法详解

在Python中处理异常使用的是try-except代码块,try-except代码块放入让python执行的操作,同时告诉python程序如果发生了异常该怎么办,try-except这个功能其实很多入门书籍中都放到了高级篇幅里,在入门的时
2022-06-04

c++捕获异常的方法是什么

在C++中,可以使用try-catch块来捕获异常。试图在try块中执行代码,如果发生异常,则会立即跳转到与异常类型匹配的catch块。catch块可以处理异常,并执行相应的操作。以下是使用try-catch块捕获异常的方法:```cppt
2023-09-14

python捕获异常的方法是什么

在Python中,可以使用try-except语句来捕获异常。语法如下:try:# 可能会产生异常的代码块except 异常类型1:# 处理异常的代码块except 异常类型2:# 处理异常的代码块...else:# 如果没有异
2023-10-26

python捕获异常的方法有哪些

在Python中,有以下几种方法可以捕获异常:1. try-except语句:使用try-except语句块可以捕获异常。在try块中编写可能出错的代码,在except块中处理捕获到的异常。```pythontry:# 可能出错的代码exc
2023-08-08

Android 捕获运行时异常详解

Android 捕获运行时异常详解Android 异常分为两类:CheckedException 和 UnCheckedExceptionCheckException:在编译代码时就需要进行try()catch捕获的。UnCheckExce
2023-05-31

oracle抛出异常和捕获异常的方法是什么

在Oracle中,抛出异常和捕获异常的方法是通过使用PL/SQL代码块来实现的。1. 抛出异常:在PL/SQL代码块中,可以使用关键字RAISE来抛出异常。抛出异常的语法如下:RAISE exception_name;其中,exceptio
2023-10-20

Android 全局异常捕获实例详解

Android 全局异常捕获今天就来说说作为程序猿的我们每天都会遇到的东西bug,出bug不可怕可怕的是没有出bug时的堆栈信息,那么对于bug的信息收集就显得尤为重要了,一般用第三方bugly或者友盟等等都能轻易收集,但是由于公司不让使用
2023-05-31

android教程之hockeyapp捕获异常示例

代码如下:package com.example.testhockeyapp;import net.hockeyapp.android.CrashManager;import net.hockeyapp.android.CrashManag
2022-06-06

springBoot2.X配置全局捕获异常的方法

本篇内容主要讲解“springBoot2.X配置全局捕获异常的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springBoot2.X配置全局捕获异常的方法”吧!springBoot2.X配
2023-06-20

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录