No Android (Java), como imprimo um rastreamento de pilha completa? Se meu aplicativo travar com nullPointerException ou algo assim, ele imprimirá um (quase) rastreamento de pilha completa da seguinte maneira:
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
No entanto, às vezes, para fins de depuração, quero registrar um rastreamento de pilha completo de onde estou no código. Imaginei que poderia fazer isso:
StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());
Mas isso apenas imprime o ponteiro para o objeto ... Preciso percorrer todos os elementos de rastreamento da pilha para imprimi-los? Ou existe um método simples para imprimir tudo?
Respostas:
Há substituições de todos os métodos de log por
(String tag, String msg, Throwable tr)
assinaturas.Passar uma exceção como terceiro parâmetro deve fornecer o rastreamento de pilha completo no logcat.
fonte
getStackTraceString()
método mencionado por @Thomas nos bastidores.O seguinte deve fazer o truque:
Observe que,
...x more
no final , não remove nenhuma informação do rastreamento de pilha:... ou em outras palavras, substitua
x more
pelas últimasx
linhas da primeira exceção.fonte
getStackTraceString()
? Não aparece no Eclipse? Não é parte deThrowable
ouException
....import android.util.Log;
).Use Log.getStackTraceString (Throwable t). Você pode obter rastreamentos de pilha mais longos cavando mais fundo. Por exemplo:
Recuperado de http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29
fonte
Log.getStackTraceString()
não registra o rastreamento de pilha, apenas o retorna como String. O código acima não registrará nada e também falhará com um NPE, see.getCause()
houvernull
.fonte
Você pode usar isto:
fonte
Você também pode imprimir um rastreamento de pilha em qualquer ponto do código do aplicativo usando métodos como
Thread.dumpStack()
Por favor, acesse o link para mais detalhes
fonte
Você precisa usar o Throwable Object para obter o stackTrace completo.
Ref: https://stackoverflow.com/a/18546861
fonte
Eu rapidamente fiz agora uma função recursiva que iterará o throwable e throwable.getCause ().
Isso ocorre porque todo "throwable.getCause ()" retorna para você uma nova mensagem de exceção com algumas linhas repetidas e novas. Portanto, o conceito é: se existe uma "causa", há uma linha com "n mais .." na tela principal de lançamento, para que eu obtenha a última linha antes da linha com "n mais ..", então recebo a mensagem de causa e finalmente, eu substring a mensagem de causa, obtendo apenas a parte após a última linha repetida (a última linha que aparece em ambos: o lançamento principal e o lançamento da causa).
Então eu uso a recursão quando recebo a mensagem de causa, e, ao chamar novamente a mesma função para obter a mensagem de causa do principal lançável, receberei uma mensagem já substituída. Se a causa jogável da lança principal também tiver outra causa, a bola principal terá 3 níveis (principal -> causa -> causa-causa), na bola principal que eu receberei a mensagem "causa" já será substituída (usando o mesmo conceito do principal
Eu tentei apenas com 2 níveis (principal -> causa) e não com mais: / Se houver algo errado, edite a função e escreva um comentário: D
tenha uma boa codificação e um bom dia também: D
Importante:
Às vezes, esse código recebe uma exceção se o "st" não contém "\ n" ou semelhante (eu encontrei algum tipo de exceção no stacktraces com esse problema). Para resolver isso, é necessário adicionar uma verificação antes da linha de código: "String r1 = ..."
Você precisa verificar: "st" contém "\ n" e se os índices de início e fim de "st.subSequence" são válidos.
De qualquer forma, sugiro colocar isso dentro de um try-catch e retornar uma string vazia em caso de exceção. (É recursiva, a sequência vazia retornada será concatenada com a sequência processada anterior).
fonte