我对此有疑问,例如,在Java类的主要方法中,我有以下代码:
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
throw new IllegalStateException("sss");
}
}).start();
try {
Thread.sleep(2000);
} catch (Exception e) {
}
System.out.println("xxx");
}
这个IllegalStateException不会阻止主方法执行,我可以看到我打印“xxx”。
然而,在Android开发中,如果我在Activity的oncreate()方法中执行相同操作,则会使App崩溃。
我想知道Android如何处理这个以及为什么它会使应用程序崩溃。
由于
logcat日志:
致命异常:Thread-248
Process: com.abc.android, PID: 3673
java.lang.IllegalStateException: sss
at com.abc.android.MainActivity$1.run(MainActivity.java:80)
at java.lang.Thread.run(Thread.java:818)
答案 0 :(得分:4)
每个线程都有一个选项来设置一个未被捕获的处理程序,当线程遇到异常时将调用该处理程序
Fron Android&here上的文档:
void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh): 设置当线程由于未捕获的异常而突然终止时调用的默认处理程序,并且没有为该线程定义其他处理程序。
未捕获的异常处理首先由线程控制,然后由线程的ThreadGroup对象控制,最后由默认的未捕获异常处理程序控制。如果线程没有明确的未捕获异常处理程序集,并且线程的线程组(包括父线程组)没有专门化其uncaughtException方法,则将调用默认处理程序的uncaughtException方法。 / p>
通过设置默认的未捕获异常处理程序,应用程序可以更改已经接受任何"默认&#34的线程处理未捕获异常的方式(例如,记录到特定设备或文件) ;系统提供的行为。
请注意,默认的未捕获异常处理程序通常不应该遵循线程的ThreadGroup对象,因为这可能会导致无限递归。
另请注意,setDefaultUncaughtExceptionHandler
是一种静态方法,这意味着它将应用于应用程序创建的所有线程。
现在,如果你深入挖掘,你会发现Android Framework为RuntimeInit.java中的所有线程定义了一个默认的未捕获异常处理程序,它继续报告崩溃并终止进程。
/**
* Use this to log a message when a thread exits due to an uncaught
* exception. The framework catches these for the main threads, so
* this should only matter for threads created by applications.
*/
private static class UncaughtHandler 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;
if (mApplicationObject == null) {
Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e);
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManagerNative.getDefault().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
} catch (Throwable t2) {
try {
Slog.e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Slog.e() fails! Oh well.
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
}
private static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
/* set default handler; this applies to all threads in the VM */
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
请记住,您可以通过调用该线程的setUncaughtExceptionHandler
覆盖特定线程的未捕获异常处理程序。如果您在上面的示例中执行此操作,您会发现应用程序不再崩溃。