Все мы слышали о журналах и знаем, как их использовать; и делаем это довольно часто. Мы любим время от времени использовать журналы, мы используем журналы для ответов API, для исключений, для простых отладок if else; для всего. Но вот в чем дело: стоит ли нам продолжать это делать? Я имею в виду, что когда мы собираемся выпустить наше приложение, мы должны просмотреть весь проект, выискивая каждый журнал, и, черт возьми, эти журналы трудно найти!

Допустим, у нас есть несколько журналов, и мы хотим использовать их при выпуске нашего приложения, как нам это сделать? Конечно, мы можем использовать нашу IDE для поиска всех строк Log . *, но в конечном итоге мы можем получить слишком много строк. Что мы будем делать, когда будут найдены сотни строк? Удалять по одному? Прокомментировать их все? И после того, как мы отправим наше приложение и снова захотим получить все наши журналы, что мы будем делать? Удалим ли мы все строки, скомпилируем ли проект, а затем выполним git checkout? Звучит немного неубедительно, не так ли?

Можно сказать : «У меня есть решение! Давайте создадим наш собственный метод журнала и проверим, является ли это сборкой DEBUG; если так, то регистрируемся, иначе - нет! ».

Что ж ... Это будет работать, однако, если мы хотим регистрировать разные уровни приоритета, нам придется либо создать несколько методов, либо добавить уровень приоритета в качестве параметра, чтобы мы могли использовать правильный журнал.

Насколько мы могли придумать достойное решение, мы все знаем, что не следует изобретать велосипед, и, как вы, возможно, знаете: есть более простое - и, возможно, лучшее - решение; встречайте Timber.

Timber - это, если кратко, API для класса Log Android. Это в основном улучшает журналы с Android. Мы делаем это, устанавливая Дерево, и каждый раз, когда мы что-то регистрируем, поведение может измениться в зависимости от того, какая реализация Дерева была вызвана.

Скачать

compile 'com.jakewharton.timber:timber:4.5.1'

Как это работает

1— Создайте экземпляр Tree и посадите его как можно скорее. (Как можно скорее означает, что мы должны добавить его в наш класс приложения в onCreate)

2 - Начните регистрацию, используя вызовы Timber, а не Log.

3 - Все, пора.

Серьезно, это так сложно.

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

Лесозаготовки с классом Timber

После того, как мы настроили наши Tree (s), мы должны начать регистрацию с использованием класса Timber, и это действительно просто. Он содержит те же методы журнала, что и класс Log, например: .v, .d, .i, .w и .e. Поскольку они похожи, если бы мы разрабатывали проект и теперь хотим использовать библиотеку Timber, мы можем просто заменить все вызовы Log. для Древесина . * звонки; но в этом нет ничего особенного, не так ли?

Заметили, что вызовы Timber не имеют тега ? Это потому, что Timber узнает, какой класс он вызван, и добавит его в свой тег .

Кроме того, у Timber есть .wtf знаменитый What The F. .. Я имею в виду, Какой ужасный провал . В отличие от ERROR, которая, как говорится в названии, является ошибкой, которая может произойти, а может и не произойти в конечном итоге, и если да, то мы знаем, как с ними справиться и как найти выход из нее. WTF обычно представляет собой настолько серьезную и проблематичную ошибку, что мы не можем исправить ее, обычно WTF должен - в зависимости от нашего приложения - завершить работу вашего приложения и отправить отчет об ошибке или что-то более важное.

Правила пуха

Timber имеет несколько удобных правил Lint. Они разделены на два набора: ошибки и предупреждения. Как вы можете себе представить, ошибки делают наше приложение неспособным компилироваться, а предупреждения делают, как говорится; показывает предупреждение, но позволяет нашему приложению скомпилировать.
Если мы предоставим неправильное количество аргументов, аргумент с другим типом при использовании интерполяции строк или теги с размером больше, чем максимальная длина Android, он вызовет error rule.
Если мы регистрируем с использованием класса Log для регистрации, a String.format или concat Строки внутри вызова Timber или регистрации исключения, это вызовет правило предупреждения.
Вы можете подробнее об этих правилах можно узнать здесь.

Посади собственное дерево

Как сказано в шаге 1, мы должны создать экземпляр Дерева и заводить его, но что это такое?
Дерево - это класс, который содержит поведение наших журналов. Чтобы создать его экземпляр, мы должны расширить Tree класс и реализовать метод журнала. Каждый раз, когда мы ведем журнал с использованием Timber, он будет проходить через Tree, который мы создаем, - если мы посадили несколько Tree, он будет проходить через все из них. - и будем вести себя так, как хотим.
Например, если мы не хотим ничего регистрировать, когда наше приложение будет выпущено, что нам делать? Итак, сначала мы создаем Дерево, которое ничего не делает в методе журнала.

Затем мы устанавливаем его в класс приложения внутри метода onCreate:

При этом никакой Timber. * никогда не будет регистрировать что-либо, но мы хотим делать это только после выпуска нашего приложения; для этого мы можем просто добавить if.

Мы в порядке! Давай проверим!

Если вы протестируете наше приложение, вы заметите, что оно ничего не регистрирует. Что случилось? Что ж, мы используем Timber. *, когда у нас нет Tree посаженного для приложения отладки! Какая жалость! Как бы то ни было, когда наше приложение выпущено, во время отладки у него нет Дерева. Как это решить? Нужно ли мне создавать дерево только для отладки? Ну… вроде как; вам не нужно его создавать, но вы должны посадить.
Timber поставляется с Tree, готовым к отладке! Встречайте DebugTree.
Просто установите, и наше приложение будет работать безупречно.

Если это приложение для отладки, оно будет использовать DebugTree, если это выпускное приложение, оно будет использовать NotLoggingTree. Мы не только исправили наше приложение, но и избавились от этого надоедливого если не.
Но послушайте, поскольку мы не ведем журнал с нашим выпущенным приложением, если что-то пойдет не так; что мы будем делать? Как насчет того, чтобы отправлять наши ошибки и предупреждения в нашу библиотеку сбоев? Звучит здорово, не правда ли?
Что ж, это действительно просто! Просто возьмите свое настраиваемое дерево и добавьте поведение, чтобы при регистрации ошибки или предупреждения он вызывал ваш библиотека сбоев!

Вот и все. Ошибки и предупреждения будут отправлены в нашу библиотеку сбоев, когда приложение будет выпущено, а все остальные уровни журнала будут проигнорированы. Нам больше не нужно искать и удалять - или комментировать - строки журналов, когда мы выпускаем наше приложение.

Но вы знаете, что? Мне не нравится этот if (BuildConfig.DEBUG). Видите ли, это своего рода if production, и это звучит странно, к счастью, мы можем решить это - и, возможно, многие другие вещи - просто создав классы для разных варианты сборки. Не знаете, как это сделать? Не волнуйся, я тебя прикрыл.

Использование вариантов сборки

Во-первых, давайте создадим класс для обработки реализации Timber, чтобы мы могли удалить логику из нашего класса Application.

Однако у нас все еще есть этот if else, я сказал, что мы прекратим его, для этого мы должны дважды создать класс TimberLogImplementation в том же пакете . Вы не ослышались: Дважды.

Для этого мы должны создать два каталога внутри src: release и debug. Внутри этого каталога мы просто создаем еще один каталог с именем java и обычно создаем пакеты, как мы это делаем в каталоге main. В представлении Project наш каталог должен выглядеть примерно так:

После его создания, в зависимости от вашего варианта сборки, IDE скомпилирует один из каталогов или другой.

После того, как мы создали это, мы реорганизуем наш класс TimberLogImplementation, класс release должен иметь только реализацию release.

В то время как наш класс debug будет иметь, как вы уже догадались, только реализацию debug.

Выполнено! Теперь, когда вы меняете вариант сборки на debug, он скомпилирует debug/java/.../TimberLogImplementation , а при переходе на release он скомпилирует release/java/.../TimberLogImplementation. Нет больше надоедливого если продакшн, все отлично! Но подождите, это еще не все! У меня последний бонус!

Скажем, мы хотим иметь больше информации в нашей отладке, например, класс и строку этого журнала. Обычно мы просто добавляем их в сообщение, например Timber.i("MyClass:13-Something happen here!"), но есть проблема - на самом деле их много, но давайте не будем усложнять - если мы добавим больше кода, строка журнала может быть другой. , мы можем между копировать и вставить добавить неправильный класс и тому подобное. К счастью, мы можем сделать следующее.

Мы перехватываем журнал нашего DebugTree, добавляя в начале имя класса и номер строки!

Если вам нужен проект с Timber, вы можете проверить этот проект, который я добавил в свой Github.

Надеюсь, вам понравилась эта небольшая статья, я скоро вернусь с другими материалами. С этого момента я надеюсь, что вы всегда будете использовать Древесину в своих проектах!

Оставайся классным :)