android自定义异常捕获,Android自定义全局异常捕捉——保存至本地

开发安卓的小伙伴都遇到过APP突然崩溃,无响应的情况.如果发生在自己手中,那么还可以通过IDE查看错误日志,但是实际都是发生在用户手中,那么这个时候产生崩溃,无响应ANR异常就很麻烦.无从下手.因此,需要全局异常捕获.也就是对未知异常,程序员没有处理的异常进行处理,记录等便于分析查找原因.

import android.content.Context;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.os.Build;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.PrintWriter;

import java.io.StringWriter;

import java.io.Writer;

import java.lang.reflect.Field;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Date;

import java.util.Locale;

/**

* @ClassName MyUncaughtExceptionHandler

* @Description 全局捕捉异常

* @Author summerain0

* @Date 2020/9/11 15:31

*/

public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

// 单例

private static MyUncaughtExceptionHandler myUncaughtExceptionHandler;

// 上下文

private Context context;

// 会输出到文件中

private StringBuilder stringBuilder;

// 系统异常处理器

private Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler;

public MyUncaughtExceptionHandler(Context context) {

this.context = context;

}

// 获取单例

public static synchronized MyUncaughtExceptionHandler getInstance(Context ctx) {

if (myUncaughtExceptionHandler == null) {

myUncaughtExceptionHandler = new MyUncaughtExceptionHandler(ctx);

}

return myUncaughtExceptionHandler;

}

// 初始化

public void init() {

defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

Thread.setDefaultUncaughtExceptionHandler(this);

}

@Override

public void uncaughtException(Thread thread, Throwable throwable) {

if (throwable == null) {

defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);

}

// 创建集合对象

stringBuilder = new StringBuilder();

// 记录时间

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS", Locale.getDefault());

String date = simpleDateFormat.format(new Date());

addMessage("崩溃时间", date);

// 记录应用版本信息

try {

PackageManager pm = context.getPackageManager();

PackageInfo pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);

addMessage("版本名", pi.versionName);

addMessage("版本号", pi.versionCode);

} catch (PackageManager.NameNotFoundException e) {

e.printStackTrace();

addMessage("error", "记录版本信息失败!" + e.getMessage());

}

// 记录设备信息

Field[] fields = Build.class.getDeclaredFields();

for (Field field : fields) {

try {

field.setAccessible(true);

Object obj = field.get(null);

if (obj != null) {

addMessage(field.getName(), obj);

}

} catch (IllegalAccessException e) {

e.printStackTrace();

addMessage("error", "记录设备信息失败!" + e.getMessage());

}

}

// 添加分隔符

addMessage(null, "==============================================================");

addMessage(null, "======================== 崩溃日志 =========================");

addMessage(null, "==============================================================");

// 记录崩溃信息

Writer writer = new StringWriter();

PrintWriter printWriter = new PrintWriter(writer);

throwable.printStackTrace(printWriter);

Throwable cause = throwable.getCause();

while (cause != null) {

cause.printStackTrace(printWriter);

cause = cause.getCause();

}

printWriter.close();

addMessage(null, writer.toString());

// 生成路径,保存至/Android/data/包名,无需读写权限

try {

File root = context.getExternalFilesDir("log");

String filename = date + ".log";

File file = new File(root, filename);

FileOutputStream fos = new FileOutputStream(file);

fos.write(stringBuilder.toString().getBytes());

fos.close();

} catch (IOException e) {

e.printStackTrace();

defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);

}

}

// 添加数据

private void addMessage(String key, Object obj) {

// 对数组做一下处理

if (obj instanceof String[]) {

String[] list = (String[]) obj;

ArrayList<String> array = new ArrayList<>(Arrays.asList(list));

stringBuilder.append(key).append("=").append(array.toString()).append("\n");

}

// 其他的都直接添加

if (key == null) {

stringBuilder.append(obj)

.append("\n");

} else {

stringBuilder.append(key)

.append("=")

.append(obj)

.append("\n");

}

}

}

import android.app.Application;

/**

* @ClassName MyApplication

* @Description TODO

* @Author summerain0

* @Date 2020/9/11 14:00

*/

public class MyApplication extends Application {

public static final String TAG = "MyApplication";

@Override

public void onCreate() {

super.onCreate();

// 初始化异常处理器

MyUncaughtExceptionHandler.getInstance(MyApplication.this).init();

}

}

android:name=".MyApplication"

....>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值