web-dev-qa-db-fra.com

Java/Android - Comment imprimer une trace de pile complète?

Sous Android (Java), comment imprimer une trace de pile complète? Si mon application se bloque suite à une exception nullPointerException, elle affiche une trace de pile (presque) complète comme ceci:

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

Cependant, parfois, à des fins de débogage, je veux enregistrer une trace de pile complète à partir de l'endroit où je me trouve dans le code. Je pensais pouvoir faire ça:

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

Mais cela ne fait qu'imprimer le pointeur sur l'objet ... Dois-je parcourir tous les éléments de trace de la pile pour les imprimer? Ou existe-t-il une méthode simple pour tout imprimer?

111
Jake Wilson

Il y a des remplacements de toutes les méthodes log avec des signatures (String tag, String msg, Throwable tr).

Passer une exception en tant que paramètre third devrait vous donner le chemin de pile complet dans logcat.

105
Philipp Reichart

Ce qui suit devrait faire l'affaire:

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

Notez que ...x more à la fin ne coupe aucune information de la trace de la pile:

(Ceci indique) que le reste de la trace de pile pour cette exception correspond au nombre indiqué d'images à partir du bas de la trace de pile de l'exception provoquée par cette exception (l'exception "englobante").

... ou en d'autres termes, remplacez x more par les dernières lignes x de la première exception.

131
Michael Berry

Utilisez Log.getStackTraceString (Throwable t). Vous pouvez obtenir des traces de pile plus longues en creusant plus profondément. Par exemple:

try {
    ...
} catch(Exception e) {
    Log.d("Some tag", Log.getStackTraceString(e.getCause().getCause()));
}

Extrait de http://developer.Android.com/reference/Android/util/Log.html#getStackTraceString%28Java.lang.Throwable%29

9
Thomas
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()));
8
faywong

Vous pouvez utiliser ceci:

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();
}
5
Mohsen Afshin

Vous pouvez également imprimer une trace de pile en tout point du code de votre application à l'aide de méthodes telles que Thread.dumpStack()

Veuillez passer par le lien pour plus de détails

2
ajaykoppisetty

Vous devez utiliser Throwable Object pour obtenir le stackTrace complet.

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();
}

Réf.: https://stackoverflow.com/a/18546861

0
Houssin Boulla