Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to automatically log the method name in Android?

I'm using this kind of pattern:

public class FooProvider extends ContentProvider {
    private static final String TAG = FooProvider.class.getSimpleName(); 
    ...

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        l.v(TAG, TAG + ".update() Uri:" + uri.toString() + " " + db.getPath());

Where l is my wrapper round Androids Log.v which takes String... args. This gives logcat output like this:

FooProvider.update() Uri: foo bar etc

What I'm looking for is a way to log the method name, in this case update(), automatically and in a way which survives refactoring the way TAG does. I've seen the class.getMethods() call but can't see a way to index the returned list with the current method at runtime.

like image 695
Carl Whalley Avatar asked Jul 31 '11 18:07

Carl Whalley


People also ask

How do you record a log on an Android phone?

Navigate to device settings and enable Developer Options (see section for ADB logs) Navigate to Developer Options and tap on Take/Submit Bug Report. Select Full Report when prompted to get the full device info along with the logs.

Is there an Android system log?

System logs are useful when something in the system throws an error. Android allows collecting system logs using Logcat. Log messages can be viewed in a Logcat window in Android Studio, or you can use the command line tool to pull them.

Which method is used to generate log messages?

The Logcat window in Android Studio displays system messages, such as when a garbage collection occurs, and messages that you added to your app with the Log class.


2 Answers

You may want to wrap these statements in a constant, so they get compiled out for your published version (which won't be printing Log.v statements anyway), but you can do something like this:

private static final boolean FINAL_CONSTANT_IS_LOCAL = true;
private static final String TAG = FooProvider.class.getSimpleName();

private String getLogTagWithMethod() {
    if (FINAL_CONSTANT_IS_LOCAL) {
        Throwable stack = new Throwable().fillInStackTrace();
        StackTraceElement[] trace = stack.getStackTrace();
        return trace[0].getClassName() + "." + trace[0].getMethodName() + ":" + trace[0].getLineNumber();
    } else {
        return TAG;
    }
}

It will depend upon how you call it to determine which StackTraceElement index you'll want, just debug it or play around a few times to find it.

When you compile your published version, just set FINAL_CONSTANT_IS_LOCAL to false and that code block will go away, always returning TAG.

like image 180
CrackerJack9 Avatar answered Oct 02 '22 13:10

CrackerJack9


It seems expensive but you could use

String Method = Thread.currentThread().getStackTrace()[2].getMethodName();

The reason you use an index of 2, is that 0 = would return currentThread and 1 = getStackTrace. This works on Java 1.5 and above, I would wrap it in some kind of if (DEBUG) {} thing so it's not in production code

Of course you will need to adjust the depth if you put that inside a method etc.

like image 27
Idistic Avatar answered Oct 02 '22 15:10

Idistic