If you don’t like use android debugger (because it is too slow on tablets or whatever) – you can use StackTraceElement to easily log your application activity.

You don’t need to put System.out in every method in your code. Just put LogUtils.trace() and you will know the exact method name and line of code.

Here’s simple sample LogUtils class:

package com.test.log;

// !!!!!
// NOTE: enabled log significantly reduces performance
// because it uses high cost getStackTrace() method, which produces huge amounts of objects
// !!!!!
public final class LogUtils {

	private static boolean sIsLogEnabled = true;
	private static String sApplicationTag = "LogDemo";

	private static final String TAG_FORMAT_METHOD = "%s:%s.%s:%d";
	private static final String FORMAT_METHOD_NAME = "%s:%d";

	private static StackTraceElement getCurrentStackTraceElement() {
		return Thread.currentThread().getStackTrace()[4];
	}

	public static void trace() {
		if (sIsLogEnabled) {
			android.util.Log.d(getMethodTag(getCurrentStackTraceElement()),
					getMethodName(getCurrentStackTraceElement()));
		}
	}

	private static String getMethodTag(StackTraceElement trace) {
		return String.format(TAG_FORMAT_METHOD, sApplicationTag,
				trace.getClassName(), trace.getMethodName(),
				trace.getLineNumber());
	}

	private static String getMethodName(StackTraceElement trace) {
		return String.format(FORMAT_METHOD_NAME, trace.getMethodName(),
				trace.getLineNumber());
	}

	public static void traceStack() {
		if (sIsLogEnabled) {
			traceStack(sApplicationTag, android.util.Log.ERROR);
		}
	}

	public static void traceStack(String tag, int priority) {
		if (sIsLogEnabled) {
			StackTraceElement[] stackTrace = Thread.currentThread()
					.getStackTrace();
			if (tag == null) {
				tag = getMethodTag(getCurrentStackTraceElement());
			}
			android.util.Log.println(priority, tag, stackTrace[4].toString());
			StringBuilder str = new StringBuilder();
			String prevClass = null;
			for (int i = 5; i < stackTrace.length; i++) {
				String className = stackTrace[i].getFileName();
				int idx = className.indexOf(".java");
				if (idx >= 0) {
					className = className.substring(0, idx);
				}
				if (prevClass == null || !prevClass.equals(className)) {
					str.append(className.substring(0, idx));
				}
				prevClass = className;
				str.append(".").append(stackTrace[i].getMethodName())
						.append(":").append(stackTrace[i].getLineNumber())
						.append("->");
			}
			android.util.Log.println(priority, tag, str.toString());
		}
	}

}

and simple Activity:

package com.test.log;

import android.app.Activity;
import android.os.Bundle;

public class LogDemoActivity extends Activity {

	private void methodB() {
		LogUtils.trace();
		LogUtils.traceStack();
	}

	private void methodA() {
		LogUtils.trace();
		methodB();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		methodA();
	}
}

The output will be:

08-04 13:55:22.020: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodA:13(31856): methodA:13
08-04 13:55:22.020: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodB:9(31856): methodB:9

08-04 13:57:25.610: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodA:14(31996): methodA:14
08-04 13:57:25.610: DEBUG/LogDemo:com.test.log.LogDemoActivity.methodB:9(31996): methodB:9
08-04 13:57:25.610: ERROR/LogDemo(31996): com.test.log.LogDemoActivity.methodB(LogDemoActivity.java:10)
08-04 13:57:25.610: ERROR/LogDemo(31996): LogDemoActivity.methodA:15->.onCreate:22->Instrumentation.callActivityOnCreate:1048->ActivityThread.performLaunchActivity:1715->.handleLaunchActivity:1767->.access$1500:122->.handleMessage:1005->Handler.dispatchMessage:99->Looper.loop:132->ActivityThread.main:4028->Method.invokeNative:-2->.invoke:491->ZygoteInit.run:844->.main:602->NativeStart.main:-2->

So you can easily trace:) Don’t forget to disable it for production.

//DL