android闪退机制,Android笔记(18)应用层Crash处理逻辑

Android发生Crash时,说明代码执行出现异常,此时的运行时环境(RunTime)将会首先感知到问题。如果此时代码设置了try-catch,将这个运行时异常RunTimeException(更加具体的可能是NPE or 数组越界等)捕获后,将不会触发运行时环境(Runtime)触发crash机制。如果一旦没有处理,将会出现Crash!!!下面我们来探讨下应用层最终崩溃的机制

RuntimeInit

protected static final void commonInit() {

LoggingHandler loggingHandler = new LoggingHandler();

RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);

Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));//importtant很重要

RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));

...

initialized = true;

}

RuntimeInit中的Thread通过setDefaultUncaugtExceptionHandler(UncaughtHandler handler)监听了当前正在运行的线程的异常行为。一旦监听到了抛出了未被捕获的异常,将会回调UncaughtHandler.uncaughtException()处理线程异常。上述代码中KillApplicationHandler就是继承自UncaughtHandler,如下

private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {

private final LoggingHandler mLoggingHandler;

/**

* Create a new KillApplicationHandler that follows the given LoggingHandler.

* If {@link #uncaughtException(Thread, Throwable) uncaughtException} is called

* on the created instance without {@code loggingHandler} having been triggered,

* {@link LoggingHandler#uncaughtException(Thread, Throwable)

* loggingHandler.uncaughtException} will be called first.

*

* @param loggingHandler the {@link LoggingHandler} expected to have run before

* this instance's {@link #uncaughtException(Thread, Throwable) uncaughtException}

* is being called.

*/

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;

// Try to end profiling. If a profiler is running at this point, and we kill the

// process (below), the in-memory buffer will be lost. So try to stop, which will

// flush the buffer. (This makes method trace profiling useful to debug crashes.)

if (ActivityThread.currentActivityThread() != null) {

ActivityThread.currentActivityThread().stopProfiling();

}

// Bring up crash dialog, wait for it to be dismissed

ActivityManager.getService().handleApplicationCrash(

mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));//通知应用响应crash

} 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 {

// Try everything to make sure this process goes away.

Process.killProcess(Process.myPid());//杀掉进程

System.exit(10);//退出进程

}

}

/**

* Ensures that the logging handler has been triggered.

*

* See b/73380984. This reinstates the pre-O behavior of

*

* {@code thread.getUncaughtExceptionHandler().uncaughtException(thread, e);}

*

* logging the exception (in addition to killing the app). This behavior

* was never documented / guaranteed but helps in diagnostics of apps

* using the pattern.

*

* If this KillApplicationHandler is invoked the "regular" way (by

* {@link Thread#dispatchUncaughtException(Throwable)

* Thread.dispatchUncaughtException} in case of an uncaught exception)

* then the pre-handler (expected to be {@link #mLoggingHandler}) will already

* have run. Otherwise, we manually invoke it here.

*/

private void ensureLogging(Thread t, Throwable e) {

if (!mLoggingHandler.mTriggered) {

try {

mLoggingHandler.uncaughtException(t, e);

} catch (Throwable loggingThrowable) {

// Ignored.

}

}

}

}

从上面的代码可以看出,RunTimeInit处理crash的步骤是打印堆栈–>通知应用–>杀掉进程

通知应用出现Crash

此时的调用栈如下

AMP.handleApplicationCrash

AMS.handleApplicationCrash

AMS.findAppProcess

AMS.handleApplicationCrashInner

AMS.addErrorToDropBox

AMS.crashApplication

AMS.makeAppCrashingLocked

AMS.startAppProblemLocked

ProcessRecord.stopFreezingAllLocked

ActivityRecord.stopFreezingScreenLocked

WMS.stopFreezingScreenLocked

WMS.stopFreezingDisplayLocked

AMS.handleAppCrashLocked

mUiHandler.sendMessage(SHOW_ERROR_MSG)

Process.killProcess(Process.myPid());

System.exit(10);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值