崩溃日志收集框架 - java crash收集流程分析

本篇文章,针对java crash处理进行分析,因为项目的原因代码选择:Android 5.0。瞄了眼,高版本代码差不多,没啥太大变化。

一、Java异常

java crash日志捕获针对的是UnChecked Exception中没有被catch住的RuntimeException。

二、Java异常捕获

1)自定义Handler 实现UncaughtExceptionHandler接口
2)Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)设置自定义Handler
3)java crash回调UncaughtExceptionHandler 的uncaughtException方法,实现奔溃信息收集,上报。

三、原理解析

这里主要就搞明白三个问题:

  • 默认的UncaughtExceptionHandler何时设置?
  • 应用发生java crash系统层都做了哪些工作?
  • uncaughtException何时回调?

下面一个个来分析:

1)默认的UncaughtExceptionHandler何时设置?

进程启动流程zygoteInit方法中:

android-5.0.0_r7/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
...
   commonInit();
...
}

private static final void commonInit() {
   /* set default handler; this applies to all threads in the VM */
   Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
...
}

很明显,这是应用进程创建过程中设置的默认UncaughtExceptionHandler。

2)应用发生java crash系统层都做了哪些工作?

这里接着上面继续看, Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
UncaughtHandler的实现:

private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
    public void uncaughtException(Thread t, Throwable e) {
     …
            // Bring up crash dialog, wait for it to be dismissed
           ActivityManagerNative.getDefault().handleApplicationCrash(
                    mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
     …
       finally {
            // Try everything to make sure this process goes away.
           Process.killProcess(Process.myPid());
           System.exit(10);
       }
    }
}

接下来整个流程总结为一个时序图:

简单总结系统层工作内容:

  • 将进程crash信息输出到/data/system/dropbox中。
  • 针对进程,调整activity及其任务栈。
  • 弹crash对话框。
  • Process.killprocess 走binder死亡回调,清理进程及其四大组件。

3)uncaughtException何时回调?

Java进程是运行在虚拟机中的,当出现运行时异常时,虚拟机会调用:

android-5.0.0_r7/art/runtime/thread.cc

void Thread::HandleUncaughtExceptions(ScopedObjectAccess& soa) {
 ...
  // Call the handler.
  tlsPtr_.jni_env->CallVoidMethod(handler.get(),
      WellKnownClasses::java_lang_Thread$UncaughtExceptionHandler_uncaughtException,
      peer.get(), exception.get());
  // If the handler threw, clear that exception too.
  tlsPtr_.jni_env->ExceptionClear();
}

JNI回调到java的uncaughtException。

你可能感兴趣的:(崩溃日志收集框架 - java crash收集流程分析)