[Программирование, Разработка под Android, Kotlin] Как писать и переиспользовать код на «‎чистом» Kotlin. Заметки Android-разработчика

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
18-Фев-2021 13:34


Как собрать в прямом эфире 17 000 зрителей? Значит, рецепт такой. Берем 15 актуальных IT-направлений, зовем зарубежных спикеров, дарим подарки за активность в чате, и вуа-ля — крупнейший в Украине и восточной Европе онлайн-ивент готов. Именно так прошла ежегодная мультитул конференция NIXMultiConf.
Под слоганом «айтишникам — от айтишников» эксперты из Украины, Беларуси, России, Великобритании и Германии поделились опытом и рассказали о новинках индустрии. Полезно было всем — дизайнерам, девелоперам, тестировщикам и менеджерам. И теперь делимся инсайтами с вами. По мотивам докладов экспертов NIX продолжаем серию материалов на самые актуальные темы.
В новой статье Вадим Савченко, Android developer в NIX, рассказывает о Kotlin и возможностях использования кода для нескольких целевых платформ.
Хочешь знать больше — смотри конференцию на YouTube-канале

Привет! Я — Вадим Савченко, Android developer в NIX. Коллеги наверняка знают: переиспользовать код — обычная практика для любого программиста. Этот подход ускоряет процесс разработки и уменьшает вероятность ошибок. Когда видишь лаконичный код, лучше фокусируешься на бизнес-логике продукта. Именно эту цель мы с командой преследовали, когда впервые взялись за Kotlin Multiplatform Mobile. На конференции NIXMulticonf я презентовал результат нашей работы. А в этой статье подробнее расскажу, как использовать код для нескольких целевых платформ и почему знание Kotlin — ценный навык.
Как часто водится на аутсорсе, заказчик хочет готовое решение быстро, качественно и от одного разработчика. Kotlin Multiplatform Mobile (далее — КММ) экономит время и усилия и помогает достигнуть желаемого результата. Команда NIX давно успешно использует Kotlin в коммерческих проектах. На этот раз мы решили пойти дальше и узнать, какие возможности дает КМM.
Суть подхода заложена в слогане на официальном сайте КММ: Save time and effort by writing the business logic for your iOS and Android apps just once. Мы можем создавать модули с общим кодом и подключать их к разным нативным приложениям на Android и IOS.
Однако «‎чистый» Kotlin не так прост, как кажется. Нетрудно отказаться от Android импортов в слое бизнес-логики, но гораздо сложнее свыкнуться с мыслью, что Java импортов тоже не должно быть. Мы посмотрели на KMM в разрезе Clean Architecture. Здесь есть явное отделение слоя бизнес-логики от остальной части приложения (слой Domain). Разбиение на слои мы сделали с помощью модулей. Так проще проконтролировать, чтобы лишний импорт и платформозависимый код не попали, куда не следует. Получили три модуля — Presentation, Domain, Data:
  • Presentation — это модуль с презентационной логикой и вьюшками;
  • Domain — бизнес-логика;
  • Data — репозитории и датасорсы.

Domain и есть наш KMM модуль, написанный на «‎чистом» Kotlin. Собрать его без проблем можно под IOS и Android. Presentation и Data — платформозависимые модули и не могут быть переиспользованы… Но это не точно. Мы решили выяснить, могут ли Data и Presentation стать KMM модулями на основе Pure Kotlin.
Сначала из Presentation выделили еще один модуль UI и закинули в него Views, Activities, Fragments. В Presentation же оставили MVP контракты и реализации презенторов. Зачастую в них можно обойтись без Android импортов. Затем из Data выделили Infrastructure. Здесь у нас DataSources и реализации Repositories, требующие Java или Android импортов. В Data остаются модельки, которыми оперирует приложение, и контракты Repositories. В итоге наши догадки оправдались: Data и Presentation тоже готовы к переиспользованию.

KMM позволяет сделать мультиплатформенными Infrastructure и View, но с ними дела обстоят сложнее. Создадим еще один простой KMM модуль для логирования. После этого вместо привычного java -> main у вас появится commonMain. androidMain и iosMain. Как же их использовать?


//Common
expect class MultiLogger() {
   fun logError()
}
//Android
actual class MultiLogger {
   actual fun logError() {
       Log.e("ERROR", "ERROR ANDROID")
   }
}
//IOS
actual class MultiLogger {
   actual fun logError() {
      println("ERROR IOS")
   }
}

В commonMain лежит «‎чистый» Kotlin-код. В случае с Domain весь код будет лежать здесь, а androidMain и iosMain нам вообще не понадобятся. Так как мы хотим, чтобы для Аndroid логирование происходило через стандартный Log, а не println(), нам нужны androidMain и iosMain. Для реализации в commonMain создали класс MultiLogger и обозначили его ключевым словом еxpect. В androidMain объявили класс MultiLogger и реализовали лог с помощью привычного нам Log. В iosMain используем println и надеемся, что он нас устроит :).
По аналогии с логером то же самое можно сделать с UI модулем и Infrastructure. Задача такого разбиения — отделить то, что может быть собрано под Android и IOS и в будущем легко реализовано на каждой из этих платформ. Если не хотите вручную писать View отдельно для двух платформ, воспользуйтесь готовыми решениями. Например, moko-widgets. Так же и с Data слоем, есть библиотека moko-permissions, которую можно взять для ваших репозиториев и не прибегать к expect и actual.
Оказалось, не всё так гладко
Когда мы впервые столкнулись с Kotlin, нас ждало несколько сюрпризов. Расскажу вам о них, чтобы вы были ко всему готовы.
Из минусов — мультиплатформенные проекты требуют новейшей версии системы сборки Gradle. Переход к старым проектам затрудняется. Если вы уже переключились на мультиплатформу, но через какое-то время вам надо вернуться в прошлый коммерческий проект, сделать это будет сложно. Gradle вечно что-то кеширует, приходится постоянно чистить кеш, но чаще это не помогает. Ок, переустанавливаем. Но на все это уходит слишком много времени.
Кроме того, нам пришлось вручную формировать пакеты и структуры папок под три Source-набора: Android main, iOS main и Common main. Также было неудобно самим создавать build.gradle.kts и прописывать в них пути к исходникам.
Также были проблемы с общением между модулями. Студия подсвечивала все импорты и сущности из соседних модулей красным и не видела их, хотя все успешно собиралось и работало.
Если до этого момента вы успешно откладывали знакомство с Coroutines, здесь уже без них никак. С помощью Корутинов на Kotlin пишут асинхронный, неблокирующий код. У нас с ними все было ОК. Но коллеги рассказывали, что иногда Coroutines могут зависнуть в iOS по непонятным причинам, и это сложно предотвратить и контролировать. Насколько я знаю из новейших источников, этот момент пофиксили. Но есть другая проблема — iOS код может выдавать ошибки, которые превращаются в базовые iOS-ные.
Сейчас почти все проблемы ушли. Вы можете использовать последнюю версию android studio, и все будет прекрасно работать. Также Kotlin Multiplatform Mobile Plugin существенно упрощает создание новых мультиплатформенных проектов и поддержку текущих и даже позволяет дебажить код, собранный под IOS.
Подводя итоги, хотелось бы сказать, что все Android-разработчики давно привыкли использовать Kotlin. Круто, что совсем немного изменив нашу структуру модулей, мы можем получить код, который будет переиспользован. Так что давайте пробовать, заводить тикеты о проблемах, с которыми сталкиваемся, поднимать комьюнити и учиться на ошибках друг друга.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_razrabotka_pod_android (Разработка под Android), #_kotlin, #_kotlin, #_blog_kompanii_nix (
Блог компании NIX
)
, #_programmirovanie (
Программирование
)
, #_razrabotka_pod_android (
Разработка под Android
)
, #_kotlin
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 20:00
Часовой пояс: UTC + 5