En Android (Java), ¿cómo imprimo una traza de pila completa? Si mi aplicación se bloquea desde nullPointerException o algo así, imprime un seguimiento (casi) completo de la pila de esta manera:
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
Sin embargo, a veces, para fines de depuración, quiero registrar un seguimiento completo de la pila desde donde estoy en el código. Pensé que podría hacer esto:
StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());
Pero esto solo imprime el puntero al objeto ... ¿Tengo que recorrer en iteración todos los elementos traza de la pila para imprimirlos? ¿O hay un método simple para imprimirlo todo?
Respuestas:
Hay anulaciones de todos los métodos de registro con
(String tag, String msg, Throwable tr)
firmas.Pasar una excepción como el tercer parámetro debería darle el seguimiento completo de la pila en logcat.
fuente
getStackTraceString()
método mencionado por @Thomas detrás de escena.Lo siguiente debería hacer el truco:
Tenga
...x more
en cuenta que al final no corta ninguna información del seguimiento de la pila:... o en otras palabras, reemplace
x more
con las últimasx
líneas de la primera excepción.fuente
getStackTraceString()
desde? ¿No aparece en Eclipse? No es parte deThrowable
oException
....import android.util.Log;
).Utilice Log.getStackTraceString (Throwable t). Puede obtener rastros de pila más largos al cavar más profundo. Por ejemplo:
Recuperado de http://developer.android.com/reference/android/util/Log.html#getStackTraceString%28java.lang.Throwable%29
fuente
Log.getStackTraceString()
no registra el seguimiento de la pila, solo lo devuelve como String. El código anterior no registrará nada y también fallará con un NPE sie.getCause()
es asínull
.fuente
Puedes usar esto:
fuente
También puede imprimir un seguimiento de la pila en cualquier punto del código de su aplicación utilizando métodos como
Thread.dumpStack()
Visite el enlace para más detalles.
fuente
Necesita usar Throwable Object para obtener el stackTrace completo.
Ref: https://stackoverflow.com/a/18546861
fuente
Rápidamente hice una función recursiva que iterará el throwable y throwable.getCause ().
Esto se debe a que cada "throwable.getCause ()" le devuelve un nuevo mensaje de excepción con algunas líneas repetidas y nuevas. Entonces, el concepto es: si hay una "causa", hay una línea con "n more .." en la línea principal, así que obtengo la última línea antes de la que tiene "n more ..", entonces recibo el mensaje de causa y finalmente subcadena el mensaje de causa obteniendo solo la parte después de la última línea repetida (la última línea que aparece en ambas: la principal arrojable y la causa arrojable).
Luego uso la recursividad cuando recibo el mensaje de causa, por lo que al volver a llamar a la misma función para obtener el mensaje de causa del elemento principal, obtendré un mensaje ya reemplazado. Si la causa que se puede lanzar desde el principal también tiene otra causa, entonces el principal que se puede lanzar tiene 3 niveles (principal -> causa -> causa de causa), en el principal que se arroja se obtiene un "mensaje de causa", un mensaje ya reemplazado (usando el mismo concepto de principal
Lo probé solo con 2 niveles (principal -> causa) y no con más: / Si hay algún problema, edite la función y escriba un comentario: D
que tengas una buena codificación y un buen día también: D
Importante:
Este código a veces recibe una excepción si el "st" no contiene "\ n" o similar (encontré algún tipo de excepciones stacktraces tienen este problema). Para resolver esto, debe agregar alguna comprobación antes de la fila de código: "String r1 = ..."
Debe comprobar: "st" contiene "\ n" y que los índices de inicio y fin de "st.subSequence" son válidos.
De todos modos, sugiero poner esto dentro de un try-catch y devolver una cadena vacía en caso de excepción. (Es recursivo, por lo que la cadena vacía devuelta se concatenará con la cadena procesada anterior).
fuente