【问题标题】:Is there any way to automatically log the method name in Android?有什么方法可以在 Android 中自动记录方法名称?
【发布时间】:2011-10-17 00:11:23
【问题描述】:

我正在使用这种模式:

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

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

FooProvider.update() Uri: foo bar etc

我正在寻找的是一种自动记录方法名称的方法,在本例中为 update(),并且这种方式可以像 TAG 那样进行重构。我见过 class.getMethods() 调用,但看不到在运行时用当前方法索引返回列表的方法。

【问题讨论】:

标签: android logging logcat


【解决方案1】:

您可能希望将这些语句包装在一个常量中,以便为您发布的版本编译它们(无论如何都不会打印 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;
    }
}

这将取决于您如何调用它来确定您需要哪个StackTraceElement 索引,只需调试它或多玩几次即可找到它。

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

【讨论】:

  • 这很巧妙。 Idistic 也很聪明 - 我希望我能奖励你们两个。
【解决方案2】:

看起来很贵,但你可以用

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

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

当然,如果您将深度放入方法等中,则需要调整深度。

【讨论】:

    【解决方案3】:

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

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

    MethodLogger methodLogger = new MethodLogger();
    

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

    methodLogger.d("optionally log some debug messages");
    

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

    methodLogger.end();
    

    结果:

    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.
    

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

    【讨论】:

      【解决方案4】:

      我有一个自定义记录器,它围绕着 android Log。

      它将显示类名、方法名和行号。

      http://www.hautelooktech.com/2011/08/15/android-logging/

      【讨论】:

      • 此链接似乎已失效。
      • 链接已失效。
      【解决方案5】:

      您可以制作这样的静态方法,并从要调试的方法的开头和结尾调用它们:

          public static void entry_log(String id) {
                      Throwable stack = new Throwable().fillInStackTrace();
                      StackTraceElement[] trace = stack.getStackTrace();
      
                          Log.v("ENTRY",
                                  id + " - " + trace[1].getClassName() + "."
                                          + trace[1].getMethodName() + ":"
                                          + trace[1].getLineNumber());
                          break;
      
                  }
      

      public void exit_log(String id) {
                  Throwable stack = new Throwable().fillInStackTrace();
                  StackTraceElement[] trace = stack.getStackTrace();
      
                      Log.v("EXIT",
                              id + " - " + trace[1].getClassName() + "."
                                      + trace[1].getMethodName() + ":"
                                      + trace[1].getLineNumber());
                      break;
      
              }
      

      我为 Android 创建了this Logging utility,除了进出日志之外,它还具有更多功能。您可能会发现它很有用。

      【讨论】:

        【解决方案6】:

        您只需要添加消息和输入到此功能即可自动创建日志

        private static String buildMsg(String msg) {
            StringBuilder buffer = new StringBuilder();
        
            if (DETAIL_ENABLE) {
                final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];
                buffer.append("[ ");
                buffer.append(Thread.currentThread().getName());
                buffer.append(": ");
                buffer.append(stackTraceElement.getFileName());
                buffer.append(": ");
                buffer.append(stackTraceElement.getLineNumber());
                buffer.append(": ");
                buffer.append(stackTraceElement.getMethodName());
            }
        
            buffer.append("() ] _____ ");
        
            buffer.append(msg);
        
            return buffer.toString();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多