(原创)Java的Crash监控原理及监控工具

前言

在进行实际的业务开发时,需要考虑到一些线上监控的需求
比如内存占用,Crash记录。
今天就来介绍下如何监控APP里面java的Crash情况。
文末做了一个工具类可以直接拿来使用

原理介绍

其实Java层的Crash监控,做起来比较简单
主要是要理解原理。
那么我们就需要先看下,系统是如何监控Crash的
Java中的Thread类中定义了一个接口: UncaughtExceptionHandler
用于处理未捕获的异常导致线程的终止(注意:catch了的是捕获不到的),
当我们的应用crash的时候,
就会调用UncaughtExceptionHandle接口的uncaughtException方法 ,
在该方法中可以获取到异常的信息
知道了这一点,再看下系统是怎么做的:
系统是在RuntimeInit类中把KillApplicationHandler作为了异常的处理类,
KillApplicationHandler实现了UncaughtExceptionHandler 接口
抛出异常时,KillApplicationHandler的uncaughtException方法就会打印堆栈信息,
并且在finally中结束程序:贴一下系统的finally代码:

 finally {
                // Try everything to make sure this process goes away.
                Process.killProcess(Process.myPid());
                System.exit(10);
            }

所以我们的思路就很明确了,基本可以分三步走:
1:得到系统的这个默认的异常处理类KillApplicationHandler,
下面这个静态方法可以直接得到

defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

2:把系统的默认处理类替换为我们自己自定义的UncaughtExceptionHandler 接口实现类
并且在我们自己的接口实现类里面完成对异常的监控
Thread也有相应的静态方法可以完成替换操作

Thread.setDefaultUncaughtExceptionHandler(new CrashListener());

3:这步很关键,在完成我们自己的监控操作后(比如打印,记录日志等),
记得把系统的默认异常处理类替换为原来的KillApplicationHandler,这样就不会影响系统的运行。
最后在finally里面替换回来,并且手动调用系统默认处理类的uncaughtException方法:

finally {
            if (defaultUncaughtExceptionHandler != null) {
                defaultUncaughtExceptionHandler.uncaughtException(t, e);
            }
        }

工具实现

最后,贴上我做的Crash监控工具类的源码:

public class CrashListener implements Thread.UncaughtExceptionHandler {

    private static Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler;
    private static Context mContext;

    private CrashListener() {

    }

    public static void init(Context applicationContext) {
        mContext = applicationContext;
        defaultUncaughtExceptionHandler =
                Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(new CrashListener());
    }

    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        //保存异常日志信息
        File dir = new File(mContext.getExternalCacheDir(), "crash_info");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        long l = System.currentTimeMillis();
        File file = new File(dir, l + ".txt");
        Log.e("print", Log.getStackTraceString(e));
        try {
            PrintWriter pw = new PrintWriter(new FileWriter(file));
            pw.println("time: xxx");
            pw.println("thread: " + t.getName());
            e.printStackTrace(pw);
            pw.flush();
            pw.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        } finally {
            if (defaultUncaughtExceptionHandler != null) {
                defaultUncaughtExceptionHandler.uncaughtException(t, e);
            }
        }
    }
}

使用起来也很简单,在你的Application里面初始化即可:

CrashListener.init(this);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值