0

我有一个 Android 应用程序最近神秘地强制关闭了一些使用 4.x 设备的用户。查看异常堆栈,似乎错误发生在我的任何代码运行之前,但我认为我正在做一些导致这种情况的事情。

*我找到原因或堆栈的方式有问题吗?否则,如果这是一个完整的堆栈跟踪,Android 是否真的有可能在我的任何代码运行之前失败?*

我发现后者不太可能,因为我UncaughtExceptionHandler在 myApplicationonCreate()方法中注册了 my ,并且我通常从我的用户那里获取文件。

我的错误记录代码如下:

Thread.UncaughtExceptionHandler使用应用程序的 . 当发生错误时,我将异常信息写入登录uncaughtException(Thread thread,Throwable ex)。这就是我找到要打印的字符串的方式:

    // Get exception info

    String newLine = "\r\n";
    String message = "Message: " + ex.getMessage();
    String cause = "Cause: " + ex.getCause();
    StackTraceElement[] stes = ex.getStackTrace();
    String stack;

    // build stack trace

    stack = "Stack: " + newLine;

    for ( int i = 0; i < stes.length; i++ )
        {
        stack += stes[i].toString();
        stack += newLine;
        }

    // print out message
    // print out cause
    // print out stack

将其输出到文件:

Message: Unable to create application com.(Modified app name for anonimity).*.*Application: java.lang.IllegalArgumentException Cause: java.lang.IllegalArgumentException Stack: android.app.ActivityThread.handleBindApplication(ActivityThread.java:4254) android.app.ActivityThread.access$1400(ActivityThread.java:140) android.app.ActivityThread$H.handleMessage(ActivityThread.java:1297) android.os.Handler.dispatchMessage(Handler.java:99) android.os.Looper.loop(Looper.java:137) android.app.ActivityThread.main(ActivityThread.java:4921) java.lang.reflect.Method.invokeNative(Native Method) java.lang.reflect.Method.invoke(Method.java:511) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805) dalvik.system.NativeStart.main(Native Method)

PS 是的,我知道 ACRA,但我现在不想使用它。

4

2 回答 2

1

也许您的应用程序导致了一个异常,该异常被捕获然后重新抛出。

您只打印最后一个异常的 Stacktrace。也许这个异常有原因(ex.getCause()不是null)。在这种情况下,您还应该打印原因的堆栈跟踪(可能是原因的原因..)。

您不必自己执行此操作。Throwable有一个很好的方法可以将完整的堆栈跟踪和回溯打印到PrintStream

public void printStackTrace(PrintStream s)

之后,您只需将其写入printStream您的日志。

于 2013-03-27T19:11:59.827 回答
1

@micha 仍然是公认的答案,但我想我会根据他的答案展示我修改后的解决方案。

      @Override
public void uncaughtException(Thread thread, Throwable ex)
    {
    // This needs to be AIR TIGHT!. Do everything in a try-catch to prevent
    // any exceptions from EVER occurring here. If an error does occur here 
    // then we will hang
    // indefinitely and get an ANR.
    try
        {
        FileManager fileMgr = FileManager.getInstance( myApp );
        String logName = "ErrorLog.log";

        // print exception to byte array

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        PrintStream printer = new PrintStream( out );
        ex.printStackTrace( printer );

        // write out byte array as string to log file.

        fileMgr.writeToLogFile( logName, out.toString(), false );
        }
    catch ( Exception e )
        {
        }

    // This allows the system to handle to exception and close the App.

    defaultHandler.uncaughtException( thread, ex );
    }

我的自定义FileManager类执行对文件的实际写入,但我使用Throwable'sprintStackTrace()来获取完整的堆栈跟踪,这比我自己可以完成的要深得多。

于 2013-06-07T16:17:39.090 回答