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
ただし、デバッグの目的で、コードの現在の場所から完全なスタックトレースを記録することがあります。私はこれを行うことができると考えました:
StackTraceElement trace = new Exception().getStackTrace();
Log.d("myapp", trace.toString());
しかし、これはオブジェクトへのポインタを出力するだけです...それらを出力するには、すべてのスタックトレース要素を反復処理する必要がありますか?または、すべてを印刷する簡単な方法はありますか?
すべての logメソッド が(String tag, String msg, Throwable tr)
署名でオーバーライドされます。
thirdパラメーターとして例外を渡すと、logcatで完全なスタックトレースが得られます。
以下はトリックを実行する必要があります。
Log.d("myapp", Log.getStackTraceString(new Exception()));
末尾の...x more
に注意してください スタックトレースから情報を切り離しません:
(これが示す)この例外のスタックトレースの残りの部分は、例外のスタックトレースの下部から指定されたフレーム数と一致するこの例外(「囲む」例外)が原因です。
...つまり、x more
を最初の例外の最後のx
行に置き換えます。
Log.getStackTraceString(Throwable t)を使用します。深く掘ることで、より長いスタックトレースを取得できます。例えば:
try {
...
} catch(Exception e) {
Log.d("Some tag", Log.getStackTraceString(e.getCause().getCause()));
}
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()));
これを使用できます:
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();
}
Thread.dumpStack()
などのメソッドを使用して、アプリコードの任意の時点でスタックトレースを印刷することもできます。
詳細 のリンクをご覧ください
完全なstackTraceを取得するには、Throwable Objectを使用する必要があります。
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();
}