Kotlin Adept Notes
1.98K subscribers
67 photos
10 videos
113 links
Канал о разработке на Kotlin и обо всем, что с ним связано
По всем вопросам и рекламе: @ajiekcx
Download Telegram
Сегодня на конференции YaTalks будет очень крутая сессия, на которой я (Алексей Панов) и Алексей Гладков будем стараться максимально закопать Flutter и возвысить KMP, другая же команда, состоящая из Геннадия Евстратова и Евгения Сатурова, будут пытаться нам противостоять.

Все это будет проходить в формате настоящих дебатов!

Так что регистрируйтесь и приходите посмотреть прямой эфир в 19:00 (мск). Заруба должна получиться просто огненной 🔥

А если вы хотите внести свой вклад в победе над Flutter, то пишите какие бы вы задали самые неудобные вопросы команде Flutter в комментариях и возможно мы возьмем их в эфир.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤‍🔥11
По мотивам прошедших дебатов хотелось бы обсудить плюсы и минусы Flutter в сравнении с KMP и Compose Multiplatform для разработки мобильных приложений.

👍Плюсы Flutter

▫️Высокопроизводительный графический движок Impeller
▫️Очень простой порог входа
▫️Куча готовых плагинов
▫️На сегодняшний день гораздо популярнее KMP
▫️В релизе с 2018 года, в отличие от вышедшего в этом году в релиз KMP и тем более Compose MP for iOS, который все ещё в альфе
▫️Flutter на iOS работает быстрее и стабильнее, чем Compose для iOS на сегодняшний день
▫️Есть киллер фичи Hot Reload / Hot Restart ускоряющие разработку
▫️На Flutter можно официально разрабатывать под Аврору и Фуксию (зачем — это уже другой вопрос)

👎Минусы Flutter

🔸Очень больно переводить существующий проект на Flutter, с KMP это можно делать просто и постепенно
🔸Dart по сравнению с Kotlin выглядит очень устаревшим, приходится писать гораздо больше кода
🔸Многопоточность в Dart с изолятами довольно ограничена по сравнению с возможностями и гибкостью корутин в Kotlin
🔸Верстка одного и того же экрана на Flutter получается примерно в 2 раза больше чем на Compose
🔸Более примитивная система сборки по сравнению с Gradle
🔸Кодогенерацию нельзя органично встроить в процесс сборки, про компиляторные плагины даже речи не идёт
🔸Нетипобезопасные платформенные каналы, все креши будут в рантайме, если где-то ошибётесь (но есть альтернатива в виде Pigeon)
🔸Множество публичных плагинов спорного качества
🔸Нет официального решения для организации многомодульного проекта (есть только инструмент Melos)
🔸Dart используется только во Flutter, в отличие от Kotlin, который используется в различных областях

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

#Flutter #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
👍151
Forwarded from Compose Broadcast (Alex Panov)
This media is not supported in your browser
VIEW IN TELEGRAM
Автор крутого доклада про компиляторные плагины для Compose с предыдущего Mobius опубликовал исходники плагинов на GitHub.

Там очень много всего интересного и полезного:
👉 Анализ стабильности параметров Composable функции
👉 Подсветка рекомпозиций в UI
👉 Автоматическая генерация и удаление testTag
👉 Логирование причин рекомпозиции и другое

Эти плагины наконец-то решают извечную проблему анализа лишних рекомпозиций и оптимизаций вашего кода в Compose, теперь делать высокопроизводительные приложения стало гораздо проще!

#compose #plugins
👍12👏3
Требования для Kotlin библиотеки в 2024 году

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

Таким образом, если вы хотите сделать качественную Kotlin библиотеку, она должна соответствовать следующим требованиям:

🔹Не нарушать обратную совместимость без строгой необходимости, как на уровне API, так и ABI
🔹Быть задокументированной. Это касается как документации в коде, так и гайдов с примерами по ее использованию. Также хорошей практикой является выносить документацию на отдельный сайт с удобной навигацией и форматированием.
🔹Иметь достаточное и качественное покрытие unit тестами
🔹Не нарушать правила семантического версионирования
🔹Иметь простой и понятный API

Все эти требования актуальны уже не первый год, но начиная с 2024 года, считаю нужно соблюдать еще одно важное правило:

❗️Если ваша Kotlin библиотека может быть мультиплатформенной, она должна быть мультиплатформенной и поддерживать максимальное количество доступных таргетов в KMP. Если вы делаете библиотеку для Jetpack Compose, то она также должна поддерживать и Compose Multiplatform.

💡 Это очень важный шаг для реализации цели по запуску любого Android приложения на любой платформе.

А что думаете вы, готовы ли вы в своих библиотеках сделать поддержку KMP? Если нет, то почему?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Попалась интересная статья (EN, 7 мин) о том как перевести такой красивый интерфейс с Jetpack Compose на Compose Multiplatform и запустить его на iOS.

Помимо переноса кода в commonMain сорсет, переработки gradle скриптов, необходимо сделать следующее:

Адаптировать ресурсы иконок, избавиться от ссылок на Android
Изменить способ работы со шрифтами для iOS
Убрать из общего кода все обращения к java классам, например к TimeUnit
Не использовать native canvas
Вынести реализацию BackHandler для разных сорсетов, поддержать обработку жестов в iOS

Исходный код примера можно посмотреть здесь
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Как опубликовать приложение с VPN в Google Play

Казалось бы, что может сложного опубликовать приложение с VPN в магазины приложений, но наш релиз в Google Play буквально задержался на год (штука про прошлогодний хлеб 😆)

Итак в чем суть, Google Play летом 2022 года ужесточили правила публикации приложений, использующих VpnService. Теперь VPN туннель могут создавать только те приложения, в которых VPN является основной функциональностью, но есть ещё несколько разрешенных кейсов.

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

Первый реджект мы получили, когда попытались опубликовать приложение в закрытое тестирование. И это было справедливо, так как мы не заполнили политику в отношении VpnService.

Мы осознали свою ошибку:
🔵Заполнили информацию по использованию VpnService
🔵Записали shorts на YouTube, как использовать VPN
🔵Написали подробную инструкцию о том как включить VPN и для чего это нужно

Однако это никак не помогло и мы снова получили реджект с тем же пояснением 🤨:

We are unable to confirm your app's declared use of VpnService as a permitted use case


Мы подумали, что неправильно выбрали разрешенный кейс использования VPN и попробовали ещё пару раз пройти ревью, но результат не изменился.

Тогда пришлось прибегнуть к апелляции и узнать, что же от нас хотят, но какого было наше удивление, когда и на апелляции нам ответили то же самое 😭

Мы начали искать похожие кейсы в интернете, спрашивать в чатах разработчиков, но это никак не помогло и когда мы уже почти сдались и хотели выпилить VPN для сборки в Google Play, случилось чудо и нам ещё раз ответили по апелляции и сказали, что все с нашим кейсом окей, с одним НО.

‼️Нужно было указать в описании на странице приложения, что в нем есть VPN и пояснить для чего он нужен.

Это было супер очевидное решение проблемы, но почему-то мы до него не дошли раньше из-за невнятных сообщений от ревьюверов.

В итоге нам удалось успешно пройти ревью, но из-за такой вот мелочи пришлось потратить уйму времени.

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

Спасибо, что дочитали до конца, всем удачных и быстрых ревью 🥂
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥185👏2
Как пошарить версии библиотек между проектами

Думаю вы знаете про достаточно новую фичу Gradle под названием Version Catalog. С помощью этого каталога можно шарить одни и те же версии библиотек между модулями в проекте, причем обновление этих версий не инвалидирует весь кеш сборки, как это было ранее с выносом библиотек в buildSrc папку, поэтому на сегодняшний день использование Version Catalog является рекомендуемым подходом.

Но как пошарить один и тот же каталог между разными проектами, которые находятся в разных репозиториях?

😐 Первое, что приходит на ум — это вынести единый .toml файл и подключать его через git submodule, но это не самое лучшее решение, так как уже недостаточно будет просто склонировать репозиторий проекта, и при этом придется внимательно следить за синхронизацией git модулей.

🙂 Гораздо лучше будет создать свой Gradle плагин, в котором будут описаны версии ваших библиотек, и затем нужно просто опубликовать и подключить его в другие проекты. Делается это гораздо проще, чем звучит! В статье (EN, 5 мин) подробно описано, как это сделать.

Но отсюда возникают другие проблемы:
1️⃣Нельзя по клику перейти в .toml файл, как это было раньше
2️⃣Новые версии библиотеки не будут подсвечиваться в студии

С первой проблемой особо ничего не поделать без написания IDEA плагина, а вот для проверки новых версий можно воспользоваться следующим плагином. Но обратите внимание, что обновления не будут автоматически проверяться у всех зависимостей, что указаны в каталоге версий, а только у тех, что подключены в gradle файле!

💬А как вы шарите общие версии библиотек между проектами?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🆒1
Наткнулся на статью "38 ошибок в Compose" и возникло строгое ощущение, что статью писало ChatGPT, ибо ошибок и неточностей там огромное количество, даже начиная с самых первых пунктов.

1. Нам предлагают написать такой код заместо обычной лямбды:


@Composable
fun MyComponent() {
var counter by remember { mutableStateOf(0) }
val clickAction = rememberUpdatedState { counter++ }

Button(onClick = { clickAction.value.invoke() }) {
Text("Clicked $counter times")
}
}


При том, что rememberUpdatedState в целом используется для другого, в примере с обычной лямбдой было бы все окей, так как Compose умеет мемоизировать лямбды со стабильным типами.

В большинстве случаев вам не нужно ничего оптимизировать – это задача команды Compose. Но если все же нужно:
🔵оберните лямбды с нестабильными типами в remember
🔵передавайте часто меняющиеся параметры как Sate или лямбду

2. Далее нам предлагают заменить вложенные layout на Box или ConstraintLayout 🤡

Тут даже комментировать не хочется, ибо в Compose есть правило одного прохода, вьюшки не меряются два раза, соответственно проблем с производительностью не будет.

Разумеется, это не все проблемы в статье, так что не верьте всему, что написано в интернете (мне тоже), а лучше читайте официальную документацию🗿
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥5🤔1🗿1
В этом году я стал одним из членов программного комитета на конференции Podlodka Android Crew.

Мы сейчас готовим 11 сезон и у нас уже есть три крутых потенциальных темы сезона:
🎨 Оптимизация UI
📈 Карьера разработчика
⚙️ Инструменты Android разработчика

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

⚙️Если у вас есть вопросы по конференции, то смело пишите в комментарии
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
Коллега из сообщества (Максим Казанцев) опубликовал в публичный доступ 6 видео из своего курса по Kotlin Multiplatform.

🔸О курсе и знакомство с автором
🔸Инициализация проекта на KMP
🔸Задачи в Gradle
🔸Подключение Desktop + Compose
🔸Добавление Android модуля
🔸Подключение iOS таргета

Курс рассчитан на разработчиков от Junior+ и выше. Поэтому если вы не работали с KMP, или создавали проект с помощью визарда, но не совсем понимали как это сделать самостоятельно, то этот курс определенно для вас!

Приятного просмотра🤔
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18🙏6👨‍💻4🤝31
Давно на этом канале не было постов, но я пришел к вам с двумя хорошими новостями:

1️⃣ Я за это время сделал один интересный доклад про привычки Android разработки, которые мешают адаптировать приложение под KMP и скоро опубликуем его в открытый доступ, так что stay tuned

2️⃣ А также мы с командой подготовили новый 11 сезон Podlodka Android Crew с темой "Оптимизация UI".

Мы старались найти классных спикеров, помочь им с подготовкой и сезон получился довольно насыщенный:
🔹 Послушаем как продавать производительность бизнесу
🔹 Узнаем как работать с такими инструментами как Perfetto, JankStats и Jetpack Macrobenchmark
🔹 Увидим на примере как оптимизировать приложение на Jetpack Compose
🔹 А также поболеем за участников баттла и сами поучаствуем в квизе по производительности UI.

Конференция стартует уже 25 марта, так что присоединяйтесь, будет круто, все подробности на сайте.

🎁Ну и куда же без розыгрыша? Давайте разыграем одну проходку на Android Crew, единственное условие – быть подписанными на этот telegram канал @kotlin_adept.

Для участия в розыгрыше достаточно нажать на кнопку «Принять участие» под следующим постом и мы определим победителя рандомно уже в это воскресенье, удачи🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥2
Розыгрыш проходки на 11 сезон конференции Podlodka Android Crew
Kotlin Adept Notes
Розыгрыш проходки на 11 сезон конференции Podlodka Android Crew
🎉 Результаты розыгрыша:

Победитель:
1. Дмитрий (@pervov_dmitry)

Проверить результаты
🔥1
Kotlin Adept Notes
Розыгрыш проходки на 11 сезон конференции Podlodka Android Crew
Выбор дополнительных победителей (в количестве 1):

Победитель:
1. Mikhail (@zykloned)

Проверить результаты
🔥2
Кастомные маски для TextField в Compose

Раньше в Android View реализовать маску для номера телефона, не говоря уже про что-то кастомное было далеко не самой простой задачей и люди, чтобы облегчить себе жизнь, использовали сторонние библиотеки, такие как Decoro.

Но теперь с приходом Compose надобность в сторонних решениях практически отпала, ведь реализовать кастомную маску для TextField можно буквально в 40 строк кода 😱, и это возможно благодаря продуманному и простому API интерфейса VisualTransformation.

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

🔸Определить как исходный текст будет трансформироваться в текст с маской

var out = ""
text.text.forEachIndexed { index, char ->
when (index) {
2 -> out += "/$char"
4 -> out += "/$char"
else -> out += char
}
}


🔸Предоставить двухсторонний маппинг для правильного смещения курсора в поле ввода

val numberOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 4) return offset + 1
return offset + 2
}

override fun transformedToOriginal(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 5) return offset - 1
return offset - 2
}
}


📘Подробнее можно почтитать в статье, где разобран случай маски для ввода даты и с полностью кастомизируемой маской

#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍41😁1
Forwarded from Android Broadcast
Media is too big
VIEW IN TELEGRAM
Немультиплатформенные привычки Android-разработки

Алексей Панов делится тем, как Android разработчику начать писать на Kotlin Multiplatform и отучиться от платформенных привычек

2:46 KMP Стек технологий
11:32 Переход с Java API
18:01 Переход с Android API
29:03 Использование Compose
36:07 Итоговые советы

Смотрите разбор на разных площадках:
👉YouTube
👉VK Video
👉Дзен

#AndroidBroadcast #кодинг
10🔥9👍51
ViewModel в KMP

Еще не так давно считалось, что ViewModel — это только Android only история и использовать ее в общем коде в мультиплатформе не получится, но в мире KMP все меняется очень быстро:
😀Google переписали ViewModel на Kotlin и адаптировали ее lifecycle под мультиплатформу
😀JetBrains сделали ее полностью мультиплатформенной, заодно адаптировав и компоузовскую навигацию

Из нюансов, нужно явно создавать инстанс ViewModel, даже с пустым конструктором! Но при этом сохранилась поддержка savedStateHandle.


@Composable
fun MyScreen(viewModel: MyViewModel = viewModel { MyViewModel(createSavedStateHandle()) }) {
...
}


Эти изменения безусловно положительно повлияют на популяризацию KMP, такими темпами скоро достаточно будет просто перенести весь код Android приложения в папку commonMain, адаптировать gradle скрипты и можно запускать приложение на любой платформе. Звучит круто, не правда ли! 👌

Но все же я не рекомендую продолжать использовать ViewModel напрямую, а думать о ней как о контейнере! Например, так реализован InstanceKeeper в Essenty.

Это дает несколько плюсов:
😀Вы можете сами управлять ЖЦ вашего компонента с логикой, делать его как синглтон, инжектить друг в друга, а не привязывать его только к ЖЦ ViewModel
😀Вы облегчаете внедрение зависимостей, так как по сути вы создаете обычный класс

Если все равно непонятно о чем речь, то советую прочитать эту статью, где подробно рассмотрена эта концепция.

А что вы думаете об использовании ViewModel в KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
Сегодня буду выступать на митапе от Usetech. Буду рассказывать обновленную версию своего доклада, ведь с тех пор картина сильно поменялась, теперь Room, ViewModel, Jetpack Navigation Compose уже можно использовать в KMP. Так что грань между Android и мультиплатформенной разработкой все больше стирается.

Поэтому если не смотрели доклад или хотите узнать, что поменялось и задать вопросы, то приходите сегодня в 15:00 мск на прямую трансляцию.

Также, помимо меня, на митапе выступят Анна Жаркова с докладом про SwiftUI и Евгений Сатуров с докладом про Flutter.

Регистрируйтесь по ссылке и до встречи🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤‍🔥1
🟥Наконец-то опубликовали мой доклад с осеннего Mobius.

В докладе много всего интересного про подкапотную магию работы Compose, а именно:

🟢Поговорим про устройство снапшотов и узнаем причем здесь базы данных
🔵Разберемся как сделать свой стейт на основе снапшотов
🟣Рассмотрим как происходит чтение и запись, как снапшоты изолируются друг от друга
🔵А также ответим на вопрос, как при изменении стейта происходит рекомпозиция функций

Приятного просмотра😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥303🎉3🦄3
Также Mobius опубликовали наш совместный с Дмитрием Григорьевым квиз по Compose🎨

Квиз состоит из 4 блоков:
🟡Разминочные вопросы
🔵Вопросы по модификаторам
🟠Вопросы по рекомпозиции
🔵Хардкорные вопросы про подкапотную магию Compose

Так что, если не смотрели, то проверьте свои знания по Compose и напишите в комментариях на сколько вопросов  удалось ответить правильно и какой вопрос показался самым сложным🤔
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥3👍1