有没有办法在Android中自动记录方法名称?

Car*_*ley 11 logging android logcat

我正在使用这种模式:

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());
Run Code Online (Sandbox Code Playgroud)

其中l是我的包装器圆形Androids Log.v,它采用String ... args.这给出了这样的logcat输出:

FooProvider.update() Uri: foo bar etc
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是一种方法来记录方法名称,在这种情况下更新(),自动并以一种方式记住TAG的重构方式.我已经看到了class.getMethods()调用,但是无法在运行时看到使用当前方法索引返回列表的方法.

Cra*_*ck9 17

您可能希望将这些语句包装在一个常量中,因此它们会针对您发布的版本编译出来(无论如何都不会打印Log.v语句),但您可以执行以下操作:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将取决于你如何调用它来确定StackTraceElement你想要的索引,只需调试它或玩几次就可以找到它.

编译已发布的版本时,只需将FINAL_CONSTANT_IS_LOCAL设置为false,该代码块将消失,并始终返回TAG.


Idi*_*tic 9

它似乎很贵,但你可以使用

String Method = Thread.currentThread().getStackTrace()[2].getMethodName();
Run Code Online (Sandbox Code Playgroud)

使用索引2的原因是0 =将返回currentThread而1 = getStackTrace.这适用于Java 1.5及更高版本,我会将它包装在某种if(DEBUG){}中,所以它不在生产代码中

当然,如果你把它放在一个方法等内,你需要调整深度.


小智 5

我创建了一个MethodLogger 类,在方法开始时实例化该类。
它计算出类名和方法名。
它还有一个方便的elapsedTime 记录器,您可以通过调用methodLogger.end() 来访问它。

用法 - 将其放在要记录的方法的开头:

MethodLogger methodLogger = new MethodLogger();
Run Code Online (Sandbox Code Playgroud)

有选择地记录一些调试消息:

methodLogger.d("optionally log some debug messages");
Run Code Online (Sandbox Code Playgroud)

要记录方法何时结束并显示自方法开始以来经过的时间:

methodLogger.end();
Run Code Online (Sandbox Code Playgroud)

结果:

D/com.domain.app.MainActivity: onCreate()
D/com.domain.app.MainActivity: onCreate() optionally log some debug messages
D/com.domain.app.MainActivity: onCreate() finished in 0.123 seconds.
Run Code Online (Sandbox Code Playgroud)

MethodLogger 类:

public class MethodLogger {

    // Private Fields
    private String tag;
    private String methodName;
    private long startTime;


    // Constructor
    public MethodLogger() {
        if (BuildConfig.DEBUG) { // Avoid doing any processing nor debug logging when built for RELEASE.
            StackTraceElement callersStackTraceElement = Thread.currentThread().getStackTrace()[3];
            tag = callersStackTraceElement.getClassName();
            methodName = callersStackTraceElement.getMethodName() + "()";
            startTime = System.currentTimeMillis();
            Log.d(tag, this.methodName);
        }
    }


    // Public Methods
    public void e(String message) {
        Log.e(tag, methodName + " " + message);
    }

    public void i(String message) {
        Log.i(tag, methodName + " " + message);
    }

    public void d(String message) {
        if (BuildConfig.DEBUG) { // Avoid doing any debug logging when built for RELEASE.
            Log.d(tag, methodName + " " + message);
        }
    }

    public void end() {
        if (BuildConfig.DEBUG) { // Avoid doing any processing nor debug logging when built for RELEASE.
            long elapsedMillis = System.currentTimeMillis() - startTime;
            Log.d(tag, String.format("%s finished in %.3f seconds.", methodName, 0.001f * elapsedMillis));
        }
    }

}
Run Code Online (Sandbox Code Playgroud)