Як більш ефективно входити в систему за допомогою лісоматеріалів

Журналювання - одна з найбільш часто використовуваних утиліт в рамках Android . Це дуже корисно при налагодженні коду, коли налагодження за точкою зупинки просто не буде працювати.

Як правило, хорошою практикою є розміщення операторів журналу у коді. Ці твердження допомагають вам відстежувати контроль потоку у вашій програмі. Так само не рекомендується мати виписки журналу в коді, готовому до випуску, оскільки ці виписки журналу може прочитати кожен, хто під’єднує свій телефон до ПК. Отже, випускаючи вашу програму до магазину відтворення, рекомендується видалити всі оператори журналу зі свого коду.

Але це може бути справжнім болем. У вашому коді так багато операторів журналу. Тепер вам потрібно знайти кожну та видалити її зі свого коду для випуску.

Ще однією проблемою механізму реєстрації за замовчуванням є те, що вам потрібно передавати TAG кожного разу, коли ви пишете оператор журналу.

Чи не було б чудово, якби оператори журналу автоматично відключали себе під час виробництва? Не було б чудово, якби оператори журналу автоматично піднімали TAG / назву класу під час реєстрації, і ви могли б зосередитись на написанні кращого коду?

Ну, такі проблеми, як і багато інших, вирішує краща бібліотека журналів в android, яка називається Timber (Джейк Уортон).

Це легка, проста у використанні бібліотека. Він піклується про більшу частину обслуговування, яке потрібно зробити під час реєстрації, щоб ви могли зосередитись більше на написанні чудового коду і менше на матеріалах обслуговування.

Давайте створимо зразок програми, щоб побачити, як ви можете включити ліс у свою програму для Android та полегшити своє життя в журналі.

Починаємо

Ми створимо простий додаток для Android з 4 кнопками. Кожна кнопка роздруковує на консолі різні оператори журналу пріоритетів.

Створіть новий проект в Android і додайте залежність для Timber у файл build.gradle рівня додатка. На момент написання цієї статті це остання версія залежності для деревини:

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

Ініціалізація деревини

Після завантаження залежності настав час ініціалізувати бібліотеку деревини. Найкраще місце для ініціалізації деревини - у класі Application, який буде активний протягом усього терміну служби програми. Отже, давайте створимо власний клас програми та ініціалізуємо в ньому нашу бібліотеку Timber :

class MainApplication : Application() { override fun onCreate() { super.onCreate() if(BuildConfig.DEBUG){ Timber.plant(Timber.DebugTree()) } }}

Створення MainActivity

Давайте тепер створимо нашу MainActivity, додавши до кожної з них 4 кнопки та встановивши прослуховувачі кліків. Ось мій файл Activity_main.xml. Я використовую ConstraintLayout як свій кореневий макет і включаю по 4 кнопки для різних рівнів реєстрації.

Тепер прийшов час встановити ці кнопки для прослуховувачів клацань і друкувати виписку з журналу кожного разу, коли натискається кнопка. Я використовую синтетичні прив’язки kotlin замість звичайних викликів findViewById або Butterknife. Ось мій файл MainActivity.kt :

class MainActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
 btn_error.setOnClickListener { onClickedError() }
 btn_info.setOnClickListener { onInfoClicked() }
 btn_debug.setOnClickListener { onDebugClicked() }
 btn_verbose.setOnClickListener { onVerboseClicked() } }
 private fun onVerboseClicked() { Timber.v("On Verbose Clicked") }
 private fun onDebugClicked() { Timber.d("On Debug Clicked.") }
 private fun onInfoClicked() { Timber.i("On Info clicked.") }
 private fun onClickedError() { Timber.e("On Error Clicked.") }
}

Зверніть увагу, що нам не потрібно було ініціалізувати будь-яку змінну TAG у нашому класі, Timber робить це автоматично за вас.

Налаштування деревини для налагодження та випуску

Зараз тут ліс справді блискучий . Те, що ми зробили до цього часу, не було нічим чудовим, просто друкували оператори журналу за натисканням кнопки. Але, як відомо, лісозаготівля у виробництві - це не дуже гарна ідея. Ми напишемо код, щоб вимкнути журнали для виробництва, зберігаючи їх увімкненими під час режиму налагодження.

Ми напишемо блок if, щоб перевірити, чи перебуває наш додаток у режимі налагодження, і ввімкнути журналювання для цього. Якщо ні, тоді ми хочемо ініціалізувати Timber за допомогою власного дерева.

Ось модифікований клас MainApplication.kt :

class MainApplication : Application() { override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { Timber.plant(object : Timber.DebugTree() { override fun createStackElementTag(element: StackTraceElement): String? { return String.format( "Class:%s: Line: %s, Method: %s", super.createStackElementTag(element), element.lineNumber, element.methodName ) } }) } else { Timber.plant(ReleaseTree()) } }}

Як бачите, ми ініціалізували деревину за допомогою спеціального ReleaseTree, коли знаходимося в режимі випуску. Тепер давайте створимо власне дерево випусків.

Створення власного дерева

Створити дерево випусків досить просто. Створіть новий клас Kotlin і розширте його за допомогою Timber.Tree. Реалізуйте всі абстрактні функції, і все готово.

Ось мій ReleaseTree.kt :

class ReleaseTree : @NotNull Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (priority == Log.ERROR || priority == Log.WARN){ //SEND ERROR REPORTS TO YOUR Crashlytics. } }
}

Як бачите, щоразу, коли виникає помилка, ми можемо надсилати журнал до такої мережі, як Firebase CrashAnalytics або Crashlytics, і не виходити з виробництва.

Результат

Переваги використання Timber проти Android Logging

Давайте розглянемо деякі переваги використання бібліотеки Timber замість утиліти Log за замовчуванням від android sdk.

  • No need to worry about TAGS: Timber generates the TAGs automatically for you so you don’t have to worry about including a global TAG in every class.
  • No need to manually remove Log statements: As already shown, it’s really easy to disable Logging for release apps. Hence, you no longer have to go through your entire code and manually remove all the logs.
  • Customized behavior on production: In production versions, you don’t want to log, although you definitely want to log any crashes that might occur. You can implement this by using a custom debug tree (as shown above) which instead of logging to the logcat, sends the logs to your crashlytics service.
  • Customized Meta-Data: You can include customized metadata with your log statements. For example, I’ve added class name, line number and method name from which the log statement is getting printed in the implementation above. Having this data at your disposal can make debugging easier.
  • Lightweight: Does not increase your app size/method count by much. Really lightweight library as it is just a wrapper over the already existing log utility.

Conclusion

For a long time I had ignored the use of log statements and printing out better logs. As my code got bigger and problems got more complex, I realized I needed to adopt better and more efficient debugging routines. Hence, using Timber is one step in the right direction.

*Important*: I’ve created a SLACK workspace for mobile developers where we can share our learnings about everything latest in Tech, especially in Android Development, RxJava, Kotlin, Flutter, and overall mobile development in general.Click on this link to join the slack workspace. It’s absolutely free!This article was originally posted at //ayusch.com/timber-for-android

Like what you read? Don’t forget to share this post on Facebook, Whatsapp, and LinkedIn.

You can follow me on LinkedIn, Quora, Twitter, and Instagram where I answer questions related to Mobile Development, especially Android and Flutter.