如何在App崩溃时执行一段代码

96
小吉快跑呀
2017.11.07 20:56* 字数 234

其实这个算是java的知识,在程序抛出无法捕捉的异常时,会触发Thread中的defaultUncaughtExceptionHandleruncaughtException方法,UncaughtExceptionHandler就是下面这个接口

public interface UncaughtExceptionHandler {
        /**
         * Method invoked when the given thread terminates due to the
         * given uncaught exception.
         * <p>Any exception thrown by this method will be ignored by the
         * Java Virtual Machine.
         * @param t the thread
         * @param e the exception
         */
        void uncaughtException(Thread t, Throwable e);
    }

当然Android中系统自己实现了这个接口,就是下面的KillApplicationHandler

/**
     * Handle application death from an uncaught exception.  The framework
     * catches these for the main threads, so this should only matter for
     * threads created by applications.  Before this method runs,
     * {@link LoggingHandler} will already have logged details.
     */
    private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) {
            try {
                // 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));
            } 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);
            }
        }
    }

在App启动时,App会执行这个语句

Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());

这样Android就完全接管了不可捕捉的异常,也就是Crash,可以看到,Android的处理到最后是把当前进程给结束了,这就是Crash后App会闪退的原因了。

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

因此我们要自己处理Crash的话也需要自己实现一个UncaughtExceptionHandler,然后在Application类中进行设置

class App : Application() {
    override fun onCreate() {
        super.onCreate()
       Thread.setDefaultUncaughtExceptionHandler(MyUncaughtExceptionHandler());
    }

这样做的好处有很多,比如可以在这里将异常上传至服务器,也可以给用户有好的提示,或者是掩盖错误,直接返回到出错之前的页面。

Android技术
Web note ad 1