Есть ли способ автоматически регистрировать имя метода в Android? - PullRequest
10 голосов
/ 31 июля 2011

Я использую этот тип шаблона:

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

Где я моя обертка вокруг Androids Log.v, которая принимает String ... args. Это дает вывод logcat следующим образом:

FooProvider.update() Uri: foo bar etc

То, что я ищу, - это способ регистрации имени метода, в данном случае update (), автоматически и таким образом, который выживает при рефакторинге, как делает TAG. Я видел вызов class.getMethods (), но не вижу способа индексировать возвращенный список с помощью текущего метода во время выполнения.

Ответы [ 7 ]

15 голосов
/ 31 июля 2011

Возможно, вы захотите обернуть эти операторы в константу, чтобы они были скомпилированы для вашей опубликованной версии (которая в любом случае не будет печатать операторы 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.

9 голосов
/ 31 июля 2011

Это кажется дорогим, но вы можете использовать

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

Причина, по которой вы используете индекс 2, состоит в том, что 0 = вернет currentThread и 1 = getStackTrace.Это работает на Java 1.5 и выше, я бы обернул это в какую-то вещь if (DEBUG) {}, чтобы она не была в рабочем коде

Конечно, вам нужно будет отрегулировать глубину, если вы поместите это вметод и т. д.

3 голосов
/ 21 марта 2018

Я создал класс MethodLogger , который я создаю в начале метода.
Он определяет имя класса и имя метода.
У него также есть удобный elapsedTime logger, к которому вы обращаетесь, вызывая 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));
        }
    }

}
2 голосов
/ 18 августа 2011

У меня есть собственный регистратор, который оборачивается вокруг журнала Android.

будет отображаться имя класса, имя метода и номер строки.

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

0 голосов
/ 02 апреля 2019

Вам нужно только добавить сообщение и ввести эту функцию для автоматического создания журнала

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();
}
0 голосов
/ 18 июня 2018

Вы можете взглянуть на код java wood library от Jake Wharton.

Действительно, основная идея в

StackTraceElement[] stackTrace = new Throwable().getStackTrace();

Возвращает массив StackTraceElement

Алгоритм выглядит как

  1. Создатьновый экземпляр Throwable и получите трассировку стека.
  2. Выберите правильный StackTraceElement
  3. Очистите его.

Пожалуйста, прочитайте больше здесь - https://medium.com/@wdziemia/timber-c733b1faa5b6

0 голосов
/ 23 октября 2013

вы можете создавать статические методы, подобные этим, и вызывать их с начала и конца методов, которые вы хотите отлаживать:

    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 с несколькими дополнительными функциями, кроме журналов входа-выхода. Вы можете найти это полезным.

...