Сегодня буду проводить публичное собеседование на YouTube канале Android Broadcast. Мы будем проектировать мультиплатформееное приложение и обсуждать Kotlin Multiplatform, Coroutines, Compose. Это уже третье по счету (раз, два) публичное собеседование в котором я принимаю участие и так как корутины и compose мы обмусолили со всех сторон, сегодня больше сосредоточимся на KMP и на практических навыках написания мультиплатформенных приложений.
Начинаем прямой эфир в 19:00 по мск, так что залетайте на трансляцию.
После трансляции, пишите комменты под этим постом👇, если вы считаете, что что-то осталось не раскрытым или просто хотите предъявить мне за то, что я плохо провожу собесы, в общем не стесняйтесь)
Начинаем прямой эфир в 19:00 по мск, так что залетайте на трансляцию.
После трансляции, пишите комменты под этим постом👇, если вы считаете, что что-то осталось не раскрытым или просто хотите предъявить мне за то, что я плохо провожу собесы, в общем не стесняйтесь)
🔥15
Combine vs flatMapLatest + map
По горячим следам вчерашнего собеса, осталось недопонимание в чем разница между этими операторами.
Для решения задачки действительно можно было бы использовать оба решения, но есть ли разница?
В случае использования flatMapLatest за место combine:
👉 Будем каждый раз при изменении токена, пересоздавать счетчик. Это не критично, но если переставить местами два flow, то будем уже каждый раз ходить в БД, и это уже плохо
👉 Если за место flatMapLatest использовать любой другой flatMap*, то получим некорректное поведение, так так не отменим ticker flow
👉 Так как flatMapLatest отменяет корутину, важно, чтобы ticker поддерживал кооперативную отмену, иначе снова получим некорректное поведение
Чтобы запомнить все разнообразие операторов и как они работают, очень советую интерактивные marble диаграммы. Этот сайт про RxJs, но на самом деле разницы особо нет, если вам каких-то операторов не хватает во Flow, то можно воспользоваться библиотекой FlowExt
#Coroutines
По горячим следам вчерашнего собеса, осталось недопонимание в чем разница между этими операторами.
Для решения задачки действительно можно было бы использовать оба решения, но есть ли разница?
В случае использования flatMapLatest за место combine:
👉 Будем каждый раз при изменении токена, пересоздавать счетчик. Это не критично, но если переставить местами два flow, то будем уже каждый раз ходить в БД, и это уже плохо
👉 Если за место flatMapLatest использовать любой другой flatMap*, то получим некорректное поведение, так так не отменим ticker flow
👉 Так как flatMapLatest отменяет корутину, важно, чтобы ticker поддерживал кооперативную отмену, иначе снова получим некорректное поведение
Чтобы запомнить все разнообразие операторов и как они работают, очень советую интерактивные marble диаграммы. Этот сайт про RxJs, но на самом деле разницы особо нет, если вам каких-то операторов не хватает во Flow, то можно воспользоваться библиотекой FlowExt
#Coroutines
🔥13👍3😱1
Какой оператор во Flow представлен на marble диаграмме ниже?
Anonymous Quiz
4%
flatMapLatest
19%
combine
52%
zip
24%
flatMapMerge
👍6😢1
Что выбрать для навигации в Compose🤨
Это довольно распространенный вопрос и на сегодняшний день выбор либ просто огромен на любой вкус и цвет. Так что же выбрать? Конечно жеDecompose решать вам на основе требований к навигации в вашем приложении.
🤖 Jetpack Compose Navigation — официальная библиотека
👍 Поддержка от Google, интеграция с ViewModel
👎 Только для Android и еще миллион минусов
🤖 Jetpack Compose Destinations — обертка над официальной либой
👍 Решает некоторые проблемы первой либы
👎 Добавляет новых проблем из-за кодогенерации и зависимости на accompanist либы
🤖 Modo — либа от создателя Cicerone, Константина Цховребова
👍 Строится на принципах UDF, очень простая
👎 Только для Android, еще не в релизе, маленькое коммьюнити
👩💻 Appyx — решение для навигации от Bumble
👍 Декларативный подход, классные анимации из коробки, поддержка KMP
👎 Только для Compose, довольно сложная, небольшое коммьюнити
👩💻 Voyager — популярная и простая либа для навигации
👍 Много интеграций с привычными инструментами, легкая в использовании, поддержка KMP
👎 Только для Compose, есть проблемы со стабильностью
🌳 Decompose — либа от Аркадия Иванова, автора MVIKotlin
👍 Единственное решение не завязанное на UI фреймворк, декларативный подход, огромная гибкость, высокая стабильность
👎 Высокий порог входа, приходится писать много кода
Есть еще решение Odyssey от Алексея Гладкова, но автор объявил о прекращении поддержки данной либы.
Таким образом настоятельно не рекомендую использовать официальное решение для навигации в любых более менее сложных приложениях. Можете посмотреть мой доклад, где я сравниваю эту либу и Decompose. Другие либы можно смело у себя использовать, но если вы проникнетесь подходом к навигации в Decompose, то можете посмотреть другой доклад, где уже разбираю как интегрироваться не только с Compose, но и SwiftUI.
Как вы поняли, я очень топлю за Decompose, хотя его сложность может многих отпугнуть, но стоит только проникнуться компонентым подходом и уже по-другому приложения писать не захочется!
#Compose #Navigation
Это довольно распространенный вопрос и на сегодняшний день выбор либ просто огромен на любой вкус и цвет. Так что же выбрать? Конечно же
Есть еще решение Odyssey от Алексея Гладкова, но автор объявил о прекращении поддержки данной либы.
Таким образом настоятельно не рекомендую использовать официальное решение для навигации в любых более менее сложных приложениях. Можете посмотреть мой доклад, где я сравниваю эту либу и Decompose. Другие либы можно смело у себя использовать, но если вы проникнетесь подходом к навигации в Decompose, то можете посмотреть другой доклад, где уже разбираю как интегрироваться не только с Compose, но и SwiftUI.
Как вы поняли, я очень топлю за Decompose, хотя его сложность может многих отпугнуть, но стоит только проникнуться компонентым подходом и уже по-другому приложения писать не захочется!
#Compose #Navigation
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥33❤6👎1
R8 full mode
Не так давно обновил проект до Gradle 8 и получил краш в релизной сборке⚪️ . Все из-за включенного по умолчанию R8 full mode. Прежде чем разберемся, что поменялось, давайте для начала вспомним, кто такой этот ваш R8.
☢️ R8 — это утилита для удаления лишнего кода, его минификации и оптимизации
Как работает
⚙️ Строит граф от рутов, помеченных -keep в правилах proguard, и удаляет все до чего не смог дотянуться
Причем тут proguard
⚙️ Ранее в Android использовался аналог R8 под названием ProGuard, правила остались для совместимости
Когда запускается
⚙️ Во время сборки с включенным флагом isMinifyEnabled
Где может стрельнуть
⚙️ При использовании рефлексии или JNI
Что за full mode
⚙️ Включает более агрессивный режим и вырезает еще больше кода. Например, классы, создаваемые только через рефлексию, должны явно помечаться через -keep правило. Также R8 удаляет сигнатуру дженериков, что стрельнуло у меня в связке Retrofit + RxJava2
❗️ Вообще хорошей практикой считается то, когда либа уже содержит необходимые правила для R8 и вам не нужно об этом задумываться, но так бывает не всегда. Например, GSON только с последней версии стал включать правила по-умолчанию, но и это работает не для всех кейсов.
📌 Подробнее почитать про R8 full mode и известные проблемы можно тут, но эти правила мне не помогли, поэтому в комментах напишу, что помогло.
Также если хотите глубже погрузиться в правила ProGuard, то рекомендую официальный мануал и андроидовскую доку.
Столкнулись ли вы с подобной проблемой на своем проекте❓
#Android #R8 #ProGuard
Не так давно обновил проект до Gradle 8 и получил краш в релизной сборке
Как работает
Причем тут proguard
Когда запускается
Где может стрельнуть
Что за full mode
Также если хотите глубже погрузиться в правила ProGuard, то рекомендую официальный мануал и андроидовскую доку.
Столкнулись ли вы с подобной проблемой на своем проекте
#Android #R8 #ProGuard
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
Этим летом проводили MobileUpdate в Екатеринбуржском офисе Контура☁️ , где было 5 крутых докладов по мобильной разработке. А теперь все записи докладов стали доступны на YouTube🟥
🤖 Влада Шамшукаева рассказала как работать с графикой в Compose, а также о том как одну и ту же задачу можно решать совершенно разными способами
🍏 Алексей Агапов набросил, что классы и паттерны проектирования вам больше не нужны, достаточно лишь функции и знания о Functional Core / Imperative Shell.
🤖 Игорь Гордеев поведал о том как уменьшать шаблонный код с помощью KSP на примере библиотеки VisualFSM
🍏 Анастасия Чупова поделилась довольно забавной историей о фейлах при работе с диплинками в SwiftUI
🤖 И наконец Евгений Мельцайкин рассказал про плагины в Gradle, как с помощью них сократить код в ваших gradle файлах и как при этом не выстрелить себе в ногу.
Я выступал в роли программного комитета и помогал ребятам с прогонами. Все докладчики постарались на славу и определенно заслуживают ваш лайк👍
P.S. Уровень монтажа и картинки просто мое почтение
#Video #iOS #Android
Я выступал в роли программного комитета и помогал ребятам с прогонами. Все докладчики постарались на славу и определенно заслуживают ваш лайк
#Video #iOS #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥9❤4
Декларативный Bottom Sheet
На мой взгляд, самый неудачный компонент в Compose из Material 2 — это Bottom Sheet. Он долгое время крашился при изменении конфигурации, его кучу раз переписывали, но все-равно на сегодняшний день он содержит много проблем:
😀 Приходится пилить костыли для работы с WindowInsets
😀 Он не прилипает к низу экрана
😀 Производительность оставляет желать лучшего
😀 Скрытие Scrim нельзя кастомизировать
А самое худшее — это его императивный API, в котором мы вынуждены управлять его показом через suspend функции show/hide, а также приходится оборачивать контент экрана в
😀 Решить проблему можно с помощью кастомной декларативной обертки
Как это работает
Показываем Bottom Sheet, если ассоциированный с ним стейт ≠ null, иначе скрываем
Особенности реализации
Нужно уметь показывать предыдущий контент, пока bottom sheet скрывается, несмотря на то, что данных уже нет
Нужно правильно вызывать лямбду
😀 Завязываться на
😀 Отслеживание изменения
Проблема😀
На текущий момент если скрыть Bottom Sheet через изменение стейта, то его скрытие можно перехватить жестом и тогда останемся в неконсистентном состоянии. Решить проблему можно либо скрытием Bottom Sheet без анимации, либо не занулять стейт, пока он не будет полностью скрыт.
😀 Гораздо лучше дела обстоят в Material 3, там из коробки Bottom Sheet уже декларативный и в нем было решено большинство проблем, только вот далеко не все используют M3 в своих проектах и, чтобы использовать его реализацию, придется копировать к себе кучу исходного кода, что тоже не круто. Таким образом если вы еще не перешли на компоузовский Bottom Sheet, то лучше пока и не торопиться😉
А как вы боретесь с проблемами с Bottom Sheet в своем проекте?
#Compose
На мой взгляд, самый неудачный компонент в Compose из Material 2 — это Bottom Sheet. Он долгое время крашился при изменении конфигурации, его кучу раз переписывали, но все-равно на сегодняшний день он содержит много проблем:
А самое худшее — это его императивный API, в котором мы вынуждены управлять его показом через suspend функции show/hide, а также приходится оборачивать контент экрана в
ModalBottomSheetLayout
. Это очень не удобно, когда нужно показать не статический контент, а полноценный экран с динамическим отображением данных и своей логикой. Как это работает
Показываем Bottom Sheet, если ассоциированный с ним стейт ≠ null, иначе скрываем
Особенности реализации
Нужно уметь показывать предыдущий контент, пока bottom sheet скрывается, несмотря на то, что данных уже нет
Нужно правильно вызывать лямбду
onDismiss
и здесь можно допустить ошибку:confirmValueChange
не вариант, так как теперь этот callback вызывается множество разsheetState.targetValue
также может привести к проблемам, так как targetValue
будет Hidden
даже если вы не до конца скрыли Bottom SheetПроблема
На текущий момент если скрыть Bottom Sheet через изменение стейта, то его скрытие можно перехватить жестом и тогда останемся в неконсистентном состоянии. Решить проблему можно либо скрытием Bottom Sheet без анимации, либо не занулять стейт, пока он не будет полностью скрыт.
А как вы боретесь с проблемами с Bottom Sheet в своем проекте?
#Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
На ближайшей конференции Mobius я буду участвовать сразу в двух сессиях:
🗓 2 ноября мы вместе с Дмитрием Григорьевым проведем крутую игру-квиз по Jetpack Compose в онлайн формате, где осветим большое количество самых разных и интересных тем из мира Compose, а участники смогут посоревноваться друг с другом за классные призы.
🗓 10 ноября уже оффлайн в Санкт-Петербурге буду рассказывать про подкапотную магию работы стейта в Compose, рассмотрим почему он далеко не так прост, как кажется на первый взгляд и почему он является важнейшим механизмом в работе всего Compose.
🎁 В связи с этим хочу устроить аттракцион невиданной щедрости провести розыгрыш билета на ближайшую конференцию Mobius. Из обязательных условий — быть подписанным на telegram канал @kotlin_adept, а также буду очень благодарен, если поделитесь ссылкой на данный канал со своими коллегами. Ведь, чем больше аудитория, тем больше мотивации чаще постить качественный контент🙂
❗️ Для участия в розыгрыше достаточно нажать на кнопку «Принять участие» под следующим постом и мы определим победителя через 24 часа.
P.S. Пожалуйста, принимайте участие в розыгрыше только, если вы планируете смотреть конференцию, пусть билет достанется тому, кому он действительно нужен!
P.S. Пожалуйста, принимайте участие в розыгрыше только, если вы планируете смотреть конференцию, пусть билет достанется тому, кому он действительно нужен!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12
Розыгрыш билета на конференцию Mobius 2023 Autumn
Code coverage для UI тестов
⚙️ Тема анализа покрытия кода Unit тестами уже не нова, для Java уже давным-давно существует библиотека JaCoCo, для Kotlin есть официальный Gradle Plugin Kover. Оба этих инструмента позволяют анализировать ваш код и генерировать различные отчеты о его покрытии Unit тестами. Это безусловно полезные инструменты для улучшения качества вашего кода и уверенности в нем.
⚙️ Но как обстоят дела с UI тестами? Можем ли мы с помощью них проанализировать процент покрытия тестами нашей бизнес логики?
⚙️ На этот вопрос ответил мой коллега из Контура, Игорь Гордеев, в своей статье на Хабре. Он рассказал, как с помощью библиотеки VisualFSM, конечных автоматов и щепотки кодогенерации сделать такое покрытие и упростить жизнь и тестировщикам, и разработчикам в тысячу раз!
Приятного чтения🤯
#Android #Testing
Приятного чтения
#Android #Testing
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍3
Compose Quiz
🔴 Ребят, напоминаю, что сегодня пройдет квиз по Jetpack Compose в 12:15 (мск) на сайте Mobius. И принять участие вы можете абсолютно бесплатно так как это Community Day, достаточно просто зарегистрироваться по ссылке.
Мы подготовили аж 40😱 вопросов по Compose и осветили все самые значимые темы, знание которых определенно поможет вам в повседневной разработке на Compose.
Так что приходите посоревноваться друг с другом, а тот кто наберёт больше всего баллов, получит хороший приз🏅
Мы подготовили аж 40
Так что приходите посоревноваться друг с другом, а тот кто наберёт больше всего баллов, получит хороший приз
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤1
VPN, который не заблокируют
🌐 Ни для кого не секрет, что сейчас все больше протоколов VPN подвергается блокировке — это и WireGuard, и OpenVPN, и другие, но решение есть!
Причём собрать свое мобильное приложение с VPN, которое не боится блокировок достаточно легко. Для этого нам потребуется связка WireGuard + xRay.
Принцип работы
😀 xRay — это прокси-сервер, который умеет маскировать трафик под браузерный (TLS). Нам лишь нужно запустить VPN туннель и весь трафик пропускать через него.
Пример на Android
😀 Запускаем xRay с переданной конфигурацией. В
😀 Подготавливаем VpnService, чтобы ваше приложение могло создавать VPN туннель.
😀 Поднимаем VPN туннель. Внутри конфига в Endpoint указываем localhost, чтобы весь трафик шел в xRay.
Как видим реализовать свое приложение для VPN с данными либами довольно не сложно🤔 . И так как эти либы написаны на Go, мы их можем запустить где угодно, будь то Android, iOS или любая другая платформа.
Если у вас остались вопросы и тема заинтересовала, то пишите комменты, попробую помочь, чем смогу👇
Причём собрать свое мобильное приложение с VPN, которое не боится блокировок достаточно легко. Для этого нам потребуется связка WireGuard + xRay.
Принцип работы
Пример на Android
inbounds
указываем входящий трафик от WireGuard с localhost и протоколом dokodemo-door
, а в outbounds
исходящий трафик на ваш сервер, тут можно использовать либо облегченный протокол vless
, либо полноценный протокол с шифрованием vmess
.
LibXray.runXray("", configFile.absolutePath, 0)
GoBackend.VpnService.prepare(context)
val backend = GoBackend(applicationContext)
val tunnel: Tunnel = WireGuardTunnel() // Ваш класс, реализующий интерфейс Tunnel
val config: Config = ... // Ваш конфиг для WireGuard
backend.setState(tunnel, Tunnel.State.UP, config) // Обязательно вызывать с фонового потока
Как видим реализовать свое приложение для VPN с данными либами довольно не сложно
Если у вас остались вопросы и тема заинтересовала, то пишите комменты, попробую помочь, чем смогу👇
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍1🤔1
Если вы находитесь на площадке Мобиуса, то всех буду ждать в первом зале или приходите посмотреть доклад онлайн, если есть такая возможность.
До встречи
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝5🔥4👍3
Compose Snapshots
❓ После доклада меня много спрашивали, а зачем мне вообще знать про снапшоты? Где эти знания применить на практике?
💡 И на мой взгляд, в первую очередь их нужно знать, чтобы разобраться, а каким образом изменение State внутри Composable функции приводит к рекомпозиции?
✳️ Давайте сначала вспомним, что вообще такое Snapshot
Это механизм, используемый внутри Compose State и не только, для работы с множественными изолированными копиями состояния. Снапшоты также позволяют сделать безопасное изменение стейта конкурентно без блокировок. Можете думать про снапшоты как про транзакции в базах данных или как про ветки в git.
✳️ Причем тут снапшоты и рекомпозиция?
Все Composable дерево заворачивается в Snapshot, поэтому на самом деле изменение стейта не происходит глобально, а происходит внутри снапшота, поэтому снапшот может отследить каждое чтение и запись любого стейта внутри, так Compose понимает какие части экрана нужно перерисовать в дальнейшем.
✳️ Где снапшоты могут пригодиться на практике?
🟠 Если вдруг вы захотите написать свою либу поверх compose runtime
🟡 Для безопасного изменения стейта с нескольких потоков
🔵 Для создания своего изменяемого Stable типа, отслеживаемого Compose
🔵 Для всего, на что способно ваше воображение! Например, почему бы не работать с БД через Compose State? Что? Да! Это тоже возможно благодаря снапшотам.
Но самое крутое и полезное применение снапшотов я покажу в следующем посте, так что stay tuned💻
#Compose #Snapshots
Это механизм, используемый внутри Compose State и не только, для работы с множественными изолированными копиями состояния. Снапшоты также позволяют сделать безопасное изменение стейта конкурентно без блокировок. Можете думать про снапшоты как про транзакции в базах данных или как про ветки в git.
Все Composable дерево заворачивается в Snapshot, поэтому на самом деле изменение стейта не происходит глобально, а происходит внутри снапшота, поэтому снапшот может отследить каждое чтение и запись любого стейта внутри, так Compose понимает какие части экрана нужно перерисовать в дальнейшем.
private inline fun <T> composing(
composition: ControlledComposition,
modifiedValues: IdentityArraySet<Any>?,
block: () -> T
): T {
val snapshot = Snapshot.takeMutableSnapshot(
readObserverOf(composition), writeObserverOf(composition, modifiedValues)
)
try {
return snapshot.enter(block)
} finally {
applyAndCheck(snapshot)
}
}
Но самое крутое и полезное применение снапшотов я покажу в следующем посте, так что stay tuned
#Compose #Snapshots
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥9
This media is not supported in your browser
VIEW IN TELEGRAM
Compose withAnimation
В SwiftUI есть очень классная фича
Не справедливо, что такого механизма нет из коробки в Compose, и инженер из Google решил исправить это недоразумение. Он сделал свой аналог
Как это работает?
1. Создается пустой словарь состояний для анимации
2. Выполняется лямбда блок внутри Snapshot, в этой лямбде могут происходить изменения стейта
3. У Snapshot вызывается
4. Данные мапятся в другой тип, откуда достаются измененные значения
5. Уничтожается Snapshot, чтобы не допустить утечек памяти, при этом изменения не применяются глобально! «Все что произошло в снапшоте, остается в снапшоте»©
6. Анимируются значения
Если у вас есть еще идеи как можно применить снапшоты, делитесь своими мыслями в комментариях👇
#Compose #Snapshots #Animations
В SwiftUI есть очень классная фича
withAnimation
, позволяющая сделать анимацию вьюшки просто путем изменения состояния, а сама анимация произойдет как по волшебству.
@State private var showDetail = false
var body: some View {
VStack {
Button("Show details") {
withAnimation {
showDetail.toggle()
}
}
if showDetail {
Text("Details")
}
}
}
Не справедливо, что такого механизма нет из коробки в Compose, и инженер из Google решил исправить это недоразумение. Он сделал свой аналог
withAnimation
и реализовал это с помощью Snapshot API, про который мы говорили ранее.Как это работает?
1. Создается пустой словарь состояний для анимации
2. Выполняется лямбда блок внутри Snapshot, в этой лямбде могут происходить изменения стейта
3. У Snapshot вызывается
writeObserver
при каждой записи в State и заполняется информация для анимации4. Данные мапятся в другой тип, откуда достаются измененные значения
5. Уничтожается Snapshot, чтобы не допустить утечек памяти, при этом изменения не применяются глобально! «Все что произошло в снапшоте, остается в снапшоте»©
6. Анимируются значения
internal suspend fun withAnimation(
adapterRegistry: StateObjectAdapterRegistry,
animationSpec: AnimationSpec<Any?>,
block: () -> Unit
) {
val statesToAnimate = mutableMapOf<Any, StateObjectAdapter>() // 1
val snapshot = Snapshot.takeMutableSnapshot(
writeObserver = { changedState ->
statesToAnimate[changedState] = checkNotNull(adapterRegistry.getAdapterFor(changedState)) // 3
}
)
val targetValues = snapshot.enter {
block() // 2
buildTargetValues(statesToAnimate) // 4
}
snapshot.dispose() // 5
animateValues(targetValues, animationSpec) // 6
}
Если у вас есть еще идеи как можно применить снапшоты, делитесь своими мыслями в комментариях👇
#Compose #Snapshots #Animations
🔥10👍2
Сегодня на конференции YaTalks будет очень крутая сессия, на которой я (Алексей Панов) и Алексей Гладков будем стараться максимально закопать Flutter и возвысить KMP, другая же команда, состоящая из Геннадия Евстратова и Евгения Сатурова, будут пытаться нам противостоять.
Все это будет проходить в формате настоящих дебатов!
Так что регистрируйтесь и приходите посмотреть прямой эфир в 19:00 (мск). Заруба должна получиться просто огненной🔥
А если вы хотите внести свой вклад в победе над Flutter, то пишите какие бы вы задали самые неудобные вопросы команде Flutter в комментариях и возможно мы возьмем их в эфир.
Все это будет проходить в формате настоящих дебатов!
Так что регистрируйтесь и приходите посмотреть прямой эфир в 19:00 (мск). Заруба должна получиться просто огненной
А если вы хотите внести свой вклад в победе над Flutter, то пишите какие бы вы задали самые неудобные вопросы команде Flutter в комментариях и возможно мы возьмем их в эфир.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤🔥1❤1
По мотивам прошедших дебатов хотелось бы обсудить плюсы и минусы 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
Это все моменты, что я смог вспомнить, если у вас есть что добавить, то не стесняйтесь писать свои мысли в комментариях
#Flutter #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤1
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
Там очень много всего интересного и полезного:
👉 Анализ стабильности параметров Composable функции
👉 Подсветка рекомпозиций в UI
👉 Автоматическая генерация и удаление testTag
👉 Логирование причин рекомпозиции и другое
Эти плагины наконец-то решают извечную проблему анализа лишних рекомпозиций и оптимизаций вашего кода в Compose, теперь делать высокопроизводительные приложения стало гораздо проще!
#compose #plugins
👍12👏3