关于Java / Android:Java / Android – 如何打印出完整的堆栈跟踪?

Java / Android - How to print out a full stack trace?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

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

1
2
StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());

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


以下应该做的伎俩:

1
Log.d("myapp", Log.getStackTraceString(new Exception()));

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

(This indicates) that the remainder of the stack trace for this exception matches the indicated number of frames from the bottom of the stack trace of the exception that was caused by this exception (the"enclosing" exception).

...或换句话说,将x more替换为第一个异常中的最后x行。


使用(String tag, String msg, Throwable tr)签名覆盖了所有日志方法。

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


1
2
3
4
5
6
7
8
9
10
11
12
13
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()));

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

1
2
3
4
5
try {
    ...
} catch(Exception e) {
    Log.d("Some tag", Log.getStackTraceString(e.getCause().getCause()));
}

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


你可以用这个:

1
2
3
4
5
6
7
8
9
public static String toString(StackTraceElement[] stackTraceElements) {
    if (stackTraceElements == null)
        return"";
    StringBuilder stringBuilder = new StringBuilder();
    for (StackTraceElement element : stackTraceElements)
        stringBuilder.append(element.toString()).append("
"
);
    return stringBuilder.toString();
}

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

请仔细阅读链接以获取更多详细信息


您需要使用Throwable Object来获取完整的stackTrace。

1
2
3
4
5
6
7
8
9
10
11
12
try{
 // code here
}catch(Exception e){
    String exception = getStackTrace(e);
}

public static String getStackTrace(final Throwable throwable) {
     final StringWriter sw = new StringWriter();
     final PrintWriter pw = new PrintWriter(sw, true);
     throwable.printStackTrace(pw);
     return sw.getBuffer().toString();
}

参考:https://stackoverflow.com/a/18546861