Как вы обычно помечаете записи журнала? (андроид)


Я предполагаю, что большинство из вас знают об android.утиль.Бревно Все методы ведения журнала принимают 'строковый тег' в качестве первого аргумента.

и как вы обычно помечаете свои журналы в своих приложениях? Я видел такой жесткий код:

public class MyActivity extends Activity {
    private static final String TAG = "MyActivity";
    //...
    public void method () {
        //...
        Log.d(TAG, "Some logging");
    }
}

Это не выглядит красиво из-за многих причин:

  • вы можете сказать мне, что этот код не имеет жестко, но это так.
  • Мои приложения может иметь любое количество классов в разные пакеты с одинаковым именем. Так что было бы трудно читать журнал.
  • он не является гибким. Вы всегда ставили частный тег поля в свой класс.

есть ли какой-нибудь аккуратный способ получить тег для класса?

11 70

11 ответов:

Я использую тег, но я инициализирую его следующим образом:

private static final String TAG = MyActivity.class.getName();

таким образом, когда я рефакторинг мой код тег также изменится соответствующим образом.

Я обычно создаю App класс, который находится в другом пакете и содержит полезные статические методы. Одним из методов является getTag() метод, таким образом, я могу получить тег везде.
App класса выглядит так:

EDIT: улучшено на br mob комментарий (Спасибо :))

public class App {

    public static String getTag() {
        String tag = "";
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        for (int i = 0; i < ste.length; i++) {
            if (ste[i].getMethodName().equals("getTag")) {
                tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
            }
        }
        return tag;
    }

}

и когда я хочу использовать это:

Log.i(App.getTag(), "Your message here");

выход getTag метод-это имя вызывающего класса (с именем пакета), а номер строки, где getTag вызывается из, Для легкой отладки.

на Android Studio - > preference - > Live Templates - > AndroidLog выберите Log.d (тег, строка).

на текст шаблона заменить

android.util.Log.d(TAG, "$METHOD_NAME$: $content$");

С

android.util.Log.d("$className$", "$METHOD_NAME$: $content$");

Image of Android menu

нажмите кнопку изменить переменные и введите className () в выражение столбец рядом с именем класса имя. image of Android menu 2

теперь, когда вы вводите ярлык logd он будет ставить

Log.d("CurrentClassName", "currentMethodName: ");

вам больше не нужно определять тег.

Мне нравится улучшать ответ Янива если у вас есть журнал в этом формате (имя файла.java: XX) xx номер строки вы можете связать ярлык таким же образом связывается, когда есть ошибка, таким образом, я могу получить прямой к линии в вопросе просто нажмите на logcat

Я положил это в мое расширенное приложение, так что я могу использовать в каждом другом файле

public static String getTag() {
    String tag = "";
    final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    for (int i = 0; i < ste.length; i++) {
        if (ste[i].getMethodName().equals("getTag")) {
            tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
        }
    }
    return tag;
}

скриншоты:

Я создал класс статических переменных, методов и классов с именем S.

ниже приведен метод ведения журнала:

public static void L(Context ctx, Object s) {
    Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}

это называется в любом классе, как S.L(this, whaterver_object); The getClass().getName() также добавляет имя пакета, следовательно, я удаляю его, чтобы не делать тег излишне длинным.

плюсы:

  1. короче Log.d(TAG,
  2. нет необходимости преобразовывать значения int в их строку. На самом деле нет необходимости вводить toString
  3. не забудем удалить Log.d когда-либо, как я просто должен удалить метод и расположение всех журналов получить помечены красным цветом.
  4. нет необходимости определять тег в верхней части действия, поскольку он принимает имя класса.
  5. тег имеет префикс CCC (короткая, простая в вводе строка), так что легко перечислить только ваши журналы в Android monitor в Android Studio. Иногда вы запускаете службы или другие классы одновременно. Если вы должны искать только по имени действия, тогда вы не можете точно видеть, когда был получен ответ службы, а затем произошло действие из вашей деятельности. Префикс, такой как CCC, помогает, поскольку он дает вам журналы хронологически с активностью, в которой это произошло

за счет обновления этих строк, когда я перемещаю код между методами или переименовываю методы, мне нравится делать следующее. Философски также кажется, что лучше сохранить "местоположение" или "контекст" в теге, а не сообщение.

public class MyClass {

    // note this is ALWAYS private...subclasses should define their own
    private static final LOG_TAG = MyClass.class.getName();

    public void f() {
        Log.i(LOG_TAG + ".f", "Merry Christmas!");
    }

}

преимущество здесь заключается в том, что вы можете отфильтровать один метод, даже если содержание не статично, например,

Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));

единственный недостаток заключается в том, что когда я переименовываю f() до g() мне нужно иметь эту строку в виду. Также, автоматический рефакторинг IDE не поймает их.

некоторое время я был поклонником использования короткого имени класса, я имею в виду LOG_TAG = MyClass.class.getSimpleName(). Я обнаружил, что их труднее фильтровать в журналах, потому что было меньше, чтобы идти дальше.

AndroidStudio есть logt шаблон по умолчанию (вы можете ввести logtи нажмите tab, чтобы он развернулся в синппет кода) . Я рекомендую использовать это, чтобы избежать копирования вставки определения тега из другого класса и забыть изменить класс, на который вы ссылаетесь. Шаблон по умолчанию расширяется до

private static final String TAG = "$CLASS_NAME$"

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

private static final String TAG = $CLASS_NAME$.class.getSimpleName();

не забудьте проверить Кнопка "Редактировать переменные" и убедитесь, что CLASS_NAME переменная определена для использования className() выражение и имеет флажок" пропустить, если определено".

вы могли бы использовать this.toString() получить уникальный идентификатор для конкретного класса, в котором вы печатаете в журнале.

это очень старый вопрос, но даже думал, что обновленный ответ на июль 2018 года предпочтительнее использовать древесину. Для регистрации правильного ведения журнала ошибки и предупреждения могут быть отправлены в сторонние библиотеки сбоев, такие как Firebase или Crashlytics.

в классе, который реализует приложение вы должны добавить это:

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.DEBUG) {
        Timber.plant(new Timber.DebugTree());
    } else {
        Timber.plant(new CrashReportingTree());
    }
}

/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
    @Override protected void log(int priority, String tag, String message, Throwable t) {
        if (priority == Log.VERBOSE || priority == Log.DEBUG) {
            return;
        }

        FakeCrashLibrary.log(priority, tag, message);

        if (t != null) {
            if (priority == Log.ERROR) {
                FakeCrashLibrary.logError(t);
            } else if (priority == Log.WARN) {
                FakeCrashLibrary.logWarning(t);
            }
        }
    }
}

Не забывайте о зависимости от древесины.

implementation 'com.jakewharton.timber:timber:4.7.1'

Я обычно использую имя метода в качестве тега, но из потока

String TAG = Thread.currentThread().getStackTrace()[1].getMethodName();

это позволяет избежать нового исключения.

private static final String TAG = new RuntimeException().getStackTrace()[0].getClassName();