10

我正在开发一个应用程序,每隔一段时间,我的一个后台工作线程就会有一个未捕获的异常。这些异常使该线程崩溃,但由于它不在 UI 线程上,因此应用程序继续运行。如何在后台线程中强制这些未捕获的异常使整个应用程序崩溃?如果相同的上下文崩溃信息(例如堆栈跟踪)可用,那就太好了。

我想这样做,以便当我将应用程序发布给我的测试人员时,它不会变得无响应。相反,当后台线程有未捕获的异常时,应用程序将转到它的崩溃处理程序并向我发送报告(我正在使用 ACRA,但这不重要)。这比静默失败的应用程序要好。

4

3 回答 3

2

迟到的答案,但我问自己同样的问题。

我们在生产环境中使用 Crashlytics,但如果应用程序是为开发而构建的,则会启用一些断言,并且记录错误实际上会抛出它,以便我们的开发人员可以检测到任何不正确的行为。

但正如您所说,在后台线程中抛出错误不会导致应用程序崩溃。

为了确保应用程序在构建开发时立即崩溃,我们只需在主循环器上使用一个处理程序来在主线程上抛出异常。

它看起来有点像这样:


public static void assertTrue(boolean condition, String msg) {
    if (condition) {
        return;
    }

    final IllegalStateException e = new IllegalStateException(message);
    if (BuildConfig.RELEASE) {
        Crashlytics.logException(e);
        return;
    }

    Log.e("ASSERT", message, e);
    if (Looper.getMainLooper() != Looper.myLooper()) {
        mMainThreadHandler.post(new Runnable() {
            @Override
            public void run() {
                throw e;
            }
        });
    }

    throw e;
}
于 2014-11-04T18:48:16.943 回答
2

以下为原版

实际上,经过进一步测试,我发现您可以通过直接将异常交给主线程来简化代码。

public static <T extends Exception> void throwOnMainThread(T exception) {
    Thread mainThread = Looper.getMainLooper().getThread();
    mainThread.getUncaughtExceptionHandler().uncaughtException(mainThread, exception);
}

这将使主线程从任何地方崩溃,即使没有设置自定义 UncaughtExceptionHandler 也可以安全调用。

原答案:

考虑以下从后台线程中使主线程崩溃的静态方法:

public static <T extends Exception> void throwOnMainThread(final T exception) {
    Handler mainThreadHandler = new Handler(Looper.getMainLooper());
    mainThreadHandler.post(new Runnable() {
        @Override
        public void run() {
            Thread currentThread = Thread.currentThread();
            currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, exception);
        }
    });
}

首先,我们通过主 Looper 获得主线程的处理程序。然后我们发布一个 Runnable,它将调用该线程的 UncaughtExceptionHandler 并将我们的异常交给它。

将其放入 utils 类中,您将能够从基本上任何地方在主线程上抛出异常。

然后可以通过使用来实现使主线程崩溃

ThreadUtils.throwOnMainThread(new RuntimeException());

例如。

于 2017-10-06T09:26:37.890 回答
0

您可以在实现的类中捕获未捕获的异常java.lang.Thread.UncaughtExceptionHandler

  • 创建一个实现 UncaughtExceptionHandler 的类,并将您想要的行为放在覆盖的uncaughtException函数中。
    您可以在此功能中执行任何您想要的行为,例如将日志发送到服务器、向用户显示自定义崩溃对话框等。
  • 在您的活动/线程中添加Thread.setDefaultUncaughtExceptionHandler();并给出您的异常处理程序类的实例。


于 2013-07-07T10:28:02.930 回答