My application is causing a force close somewhere but instead of getting a FATAL EXCEPTION with the usual (and very informative) stack trace in my LogCat, I only receive only the following 4 lines:
我的应用程序在某个地方导致了一个强制关闭,但是在我的LogCat中,我没有得到通常(而且非常有用)的堆栈跟踪的致命异常,我只收到以下4行:
06-27 07:08:54.546: D/dalvikvm(14351): GC_FOR_MALLOC freed 9923 objects / 657416 bytes in 21ms
06-27 07:08:54.769: W/dalvikvm(14351): threadid=20: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: W/dalvikvm(14351): threadid=21: thread exiting with uncaught exception (group=0x4001d7f0)
06-27 07:08:54.796: I/Process(14351): Sending signal. PID: 14351 SIG: 9
This is in DEBUG mode with NO FILTERS applied on the LogCat!
这是在调试模式中,没有对LogCat应用过滤器!
- What could be causing this behavior?
- 是什么导致了这种行为?
- Is there a way to tell what's causing this exception?
- 有什么方法可以告诉我们是什么导致了这个异常吗?
Update: Thanks to @assylias below, I've been able to implement:
更新:感谢下面的@assylias,我能够实现:
final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
Log.getStackTraceString(paramThrowable);
subclass.uncaughtException(paramThread, paramThrowable);
}
});
Which produced these added lines:
产生了这些增加的线条:
06-27 08:24:47.105: D/dalvikvm(15475): GC_FOR_MALLOC freed 13865 objects / 1435952 bytes in 45ms
06-27 08:24:47.136: I/dalvikvm(15475): threadid=15: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.136: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x45209338 (56 left)
06-27 08:24:47.140: I/dalvikvm(15475): expanding stack end (0x45209300 to 0x45209000)
06-27 08:24:47.140: I/dalvikvm(15475): Shrank stack (to 0x45209300, curFrame is 0x4520937c)
06-27 08:24:47.159: I/dalvikvm(15475): threadid=16: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.159: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x4520c338 (56 left)
06-27 08:24:47.167: I/dalvikvm(15475): expanding stack end (0x4520c300 to 0x4520c000)
06-27 08:24:47.167: I/dalvikvm(15475): Shrank stack (to 0x4520c300, curFrame is 0x4520c37c)
06-27 08:24:47.175: I/dalvikvm(15475): threadid=17: stack overflow on call to Ljava/lang/AbstractStringBuilder;.enlargeBuffer:VI
06-27 08:24:47.175: I/dalvikvm(15475): method requires 28+20+20=68 bytes, fp is 0x4520f338 (56 left)
06-27 08:24:47.175: I/dalvikvm(15475): expanding stack end (0x4520f300 to 0x4520f000)
06-27 08:24:47.175: I/dalvikvm(15475): Shrank stack (to 0x4520f300, curFrame is 0x4520f37c)
This is certainly much more useful information, but now I'm struggling with the following:
这当然是更有用的信息,但现在我正在努力解决以下问题:
- The application doesn't force-close now, despite the call to
subclass.uncaughtException()
. Why? - 尽管调用了subclass. unctexception(),但应用程序现在并没有强制关闭。为什么?
- What is the meaning of all those stack overflows? What could I be doing that's so taxing on my poor Android test device?
- 这些堆栈溢出是什么意思?我能做什么,让我可怜的Android测试设备如此吃力?
- How can I tell which part in my code causes this?
- 我怎么知道代码中哪个部分导致了这个?
Update: Log.getStackTraceString(paramThrowable);
wasn't actually printing anything. The extra print that I received was from the bogus subclass.uncaughtException(paramThread, paramThrowable); The right way of logging the full stack trace is by using Log.e(TAG, "uncaughtException", throwable).
更新:Log.getStackTraceString(paramThrowable);不是印刷任何东西。我收到的额外打印来自伪子类。uncaughtException(paramThread paramThrowable);记录完整堆栈跟踪的正确方法是使用Log。e(标签,“uncaughtException throwable)。
The only question remaining now is how do I re-throw the exception? Just do a throw paramThrowable
?
现在剩下的问题是如何重新抛出异常?仅仅做一个抛掷参数?
Answering my last question: Eclipse won't let me throw without surrounding with try/catch, which led me to understand that what I want is not a re-throw but a killProcess()
. Problem solved.
回答我的最后一个问题:Eclipse不会让我在没有try/catch的情况下抛出,这让我明白我想要的不是重新抛出而是一个killProcess()。问题解决了。
3 个解决方案
#1
18
You could set a default uncaught exception handler at the beginning of your app and log some data in there (example below is using a java logger but easy to transpose to Android):
您可以在应用程序的开头设置一个默认的未捕获异常处理程序,并在其中记录一些数据(下面的示例是使用java日志程序,但很容易转到Android):
private static void setDefaultUncaughtExceptionHandler() {
try {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
logger.error("Uncaught Exception detected in thread {}", t, e);
}
});
} catch (SecurityException e) {
logger.error("Could not set the Default Uncaught Exception Handler", e);
}
}
#2
2
this is going to be tedious, but i would single step through until it breaks with the debugger. then you can add a more general catch
这将是很乏味的,但是我将一步一步地完成,直到它与调试器中断。然后你可以添加一个更一般的捕捉
catch(Exception e){ }
捕获(异常e){ }
All exceptions extend from Exception so that may help you further diagnose you're problem.
所有异常都从异常扩展开来,这样可以帮助您进一步诊断您的问题。
One more idea, perhaps you're app is running up the device memory. The JVM could be killing you're app without telling you because of a JVM shutdown on memory error.
还有一个想法,也许你的应用程序正在运行设备内存。由于内存错误导致JVM关闭,JVM可能会在不通知您的情况下杀死您的应用程序。
#3
0
I know this is old but if anyone else wants to know about exiting as normal after dealing with the uncaught exception:
我知道这已经是老生常谈了,但如果有人想知道在处理未被发现的异常后如何正常退出:
final Thread.UncaughtExceptionHandler androidDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread, final Throwable ex) {
// Handle exception however you want, then:
androidDefaultUEH.uncaughtException(thread, ex);
}
});
#1
18
You could set a default uncaught exception handler at the beginning of your app and log some data in there (example below is using a java logger but easy to transpose to Android):
您可以在应用程序的开头设置一个默认的未捕获异常处理程序,并在其中记录一些数据(下面的示例是使用java日志程序,但很容易转到Android):
private static void setDefaultUncaughtExceptionHandler() {
try {
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
logger.error("Uncaught Exception detected in thread {}", t, e);
}
});
} catch (SecurityException e) {
logger.error("Could not set the Default Uncaught Exception Handler", e);
}
}
#2
2
this is going to be tedious, but i would single step through until it breaks with the debugger. then you can add a more general catch
这将是很乏味的,但是我将一步一步地完成,直到它与调试器中断。然后你可以添加一个更一般的捕捉
catch(Exception e){ }
捕获(异常e){ }
All exceptions extend from Exception so that may help you further diagnose you're problem.
所有异常都从异常扩展开来,这样可以帮助您进一步诊断您的问题。
One more idea, perhaps you're app is running up the device memory. The JVM could be killing you're app without telling you because of a JVM shutdown on memory error.
还有一个想法,也许你的应用程序正在运行设备内存。由于内存错误导致JVM关闭,JVM可能会在不通知您的情况下杀死您的应用程序。
#3
0
I know this is old but if anyone else wants to know about exiting as normal after dealing with the uncaught exception:
我知道这已经是老生常谈了,但如果有人想知道在处理未被发现的异常后如何正常退出:
final Thread.UncaughtExceptionHandler androidDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(final Thread thread, final Throwable ex) {
// Handle exception however you want, then:
androidDefaultUEH.uncaughtException(thread, ex);
}
});