Java/Android - 如何打印出完整的堆栈跟踪?

Jak*_*son 120 java stack android exception stack-trace

在Android(Java)中,如何打印出完整的堆栈跟踪?如果我的应用程序从nullPointerException或其他东西崩溃,它会打印出一个(几乎)完整的堆栈跟踪,如下所示:

java.io.IOException: Attempted read from closed stream.
com.android.music.sync.common.SoftSyncException: java.io.IOException: Attempted read from closed stream.
    at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:545)
    at com.android.music.sync.google.MusicSyncAdapter.fetchDataFromServer(MusicSyncAdapter.java:488)
    at com.android.music.sync.common.AbstractSyncAdapter.download(AbstractSyncAdapter.java:417)
    at com.android.music.sync.common.AbstractSyncAdapter.innerPerformSync(AbstractSyncAdapter.java:313)
    at com.android.music.sync.common.AbstractSyncAdapter.onPerformLoggedSync(AbstractSyncAdapter.java:243)
    at com.google.android.common.LoggingThreadedSyncAdapter.onPerformSync(LoggingThreadedSyncAdapter.java:33)
    at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:164)
Caused by: java.io.IOException: Attempted read from closed stream.
    at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:148)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
    at java.util.zip.GZIPInputStream.readFully(GZIPInputStream.java:212)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:64)
    at android.net.http.AndroidHttpClient.getUngzippedContent(AndroidHttpClient.java:218)
    at com.android.music.sync.api.MusicApiClientImpl.createAndExecuteMethod(MusicApiClientImpl.java:312)
    at com.android.music.sync.api.MusicApiClientImpl.getItems(MusicApiClientImpl.java:588)
    at com.android.music.sync.api.MusicApiClientImpl.getTracks(MusicApiClientImpl.java:638)
    at com.android.music.sync.google.MusicSyncAdapter.getChangesFromServerAsDom(MusicSyncAdapter.java:512)
    ... 6 more
Run Code Online (Sandbox Code Playgroud)

但有时,出于调试目的,我想从代码中的位置记录完整的堆栈跟踪.我想我可以这样做:

StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());
Run Code Online (Sandbox Code Playgroud)

但是这只是打印出指向对象的指针......我是否必须遍历所有堆栈跟踪元素才能将它们打印出来?或者有一种简单的方法可以将它全部打印出来吗?

Mic*_*rry 142

以下应该做的伎俩:

Log.d("myapp", Log.getStackTraceString(new Exception()));
Run Code Online (Sandbox Code Playgroud)

请注意,...x more最后不会切断堆栈跟踪中的任何信息:

(这表示)此异常的堆栈跟踪的剩余部分与此异常("封闭"异常)引起的异常的堆栈跟踪底部的指示帧数相匹配.

......或换句话说,用第一个例外x more的最后x一行替换.

  • 最后"还有6个"并没有切断任何信息.它告诉你,堆栈跟踪的其余部分与顶部异常的相同.只需看看第一个例外的最后6行. (9认同)

Phi*_*art 116

有签名的所有日志方法都有覆盖(String tag, String msg, Throwable tr).

传递异常作为第三个参数应该在logcat中提供完整的堆栈跟踪.

  • 我已经开发了Android两年了,之前从未注意到这一点.非常感谢你. (6认同)
  • 仅供参考三参数日志方法使用[`getStackTraceString()`](http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29)方法@Thomas在幕后. (4认同)

Tho*_*mas 10

使用Log.getStackTraceString(Throwable t).通过深入挖掘可以获得更长的堆栈跟踪.例如:

try {
    ...
} catch(Exception e) {
    Log.d("Some tag", Log.getStackTraceString(e.getCause().getCause()));
}
Run Code Online (Sandbox Code Playgroud)

http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29收到


小智 9

private static String buildStackTraceString(final StackTraceElement[] elements) {
    StringBuilder sb = new StringBuilder();
    if (elements != null && elements.length > 0) {
        for (StackTraceElement element : elements) {
            sb.append(element.toString());
        }
    }
    return sb.toString();
}


// call this at your check point
Log.d(TAG, buildStackTraceString(Thread.currentThread().getStackTrace()));
Run Code Online (Sandbox Code Playgroud)


Moh*_*hin 6

你可以用这个:

public static String toString(StackTraceElement[] stackTraceElements) {
    if (stackTraceElements == null)
        return "";
    StringBuilder stringBuilder = new StringBuilder();
    for (StackTraceElement element : stackTraceElements)
        stringBuilder.append(element.toString()).append("\n");
    return stringBuilder.toString();
}
Run Code Online (Sandbox Code Playgroud)


aja*_*tty 5

您还可以使用以下方法在应用程序代码中的任何点打印堆栈跟踪 Thread.dumpStack()

请通过链接了解更多详情