App 进程

RuntimeInit#commonInit

@UnsupportedAppUsage
protected static final void commonInit() {
    if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
 
    LoggingHandler loggingHandler = new LoggingHandler();
    RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);
    // 注册处理器
    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
		...
}

KillApplicationHandler

private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
        private final LoggingHandler mLoggingHandler;

        public KillApplicationHandler(LoggingHandler loggingHandler) {
            this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
        }

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            try {
								// 在控制台打印崩溃日志信息
                ensureLogging(t, e);

                // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
                if (mCrashing) return;
                mCrashing = true;

								...

                // 调用 AMS handleApplicationCrash,弹出对话框
                ActivityManager.getService().handleApplicationCrash(
                        mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
            } catch (Throwable t2) {
                if (t2 instanceof DeadObjectException) {
                    // System process is dead; ignore
                } else {
                    try {
                        Clog_e(TAG, "Error reporting crash", t2);
                    } catch (Throwable t3) {
                        // Even Clog_e() fails!  Oh well.
                    }
                }
            } finally {
                // kill 进程
                Process.killProcess(Process.myPid());
                System.exit(10);
            }
        }
        
    }
		private void ensureLogging(Thread t, Throwable e) {
            if (!mLoggingHandler.mTriggered) {
                try {
                    mLoggingHandler.uncaughtException(t, e);
                } catch (Throwable loggingThrowable) {
                    // Ignored.
                }
            }
        }
}

system_server 进程

ActivityManagerService#handleApplicationCrash

public void handleApplicationCrash(IBinder app,
            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
        ProcessRecord r = findAppProcess(app, "Crash");
        final String processName = app == null ? "system_server"
                : (r == null ? "unknown" : r.processName);

        handleApplicationCrashInner("crash", r, processName, crashInfo);
    }

AMS端在收到App的崩溃后,大概流程如下:

  1. 把崩溃信息通过 DBS 服务,写入到Dropbox文件中。dropbox支持错误类型:crash、wtf、anr
  2. 停止崩溃进程接收广播;增加ServiceRecord中的 crash count 数;销毁所有的 activities;
  3. 弹出崩溃对话框,等待用户选择 3.1. 如果选择重新启动,则从最近任务列表中找到崩溃进程,再次拉起 3.2. 如果选择强制退出,则杀掉app,进入kill流程 3.3. 如果选择显示应用信息,则启动系统页面的intent,打开应用详情页面

处理流程如下:

app_crash.jpeg

参考

理解Android Crash处理流程 - Gityuan博客 | 袁辉辉的技术博客

理解Android Java crash 处理流程 - 掘金