Мы в команде недавно подняли свой сервис автоматизации на Kotlin и реализовали там много всяких полезных штук:
🟣 Интеграция YouTrack и GitLab для автоматического перевода тасок в актуальное состояние и заполнения данных
🟣 Напоминание о забытых ревью
🟣 Уведомления о релизах
🟣 И другие полезные мелочи
🔖 Подробнее о наших процессах и как мы делали такой сервер читайте в статье.
〰️ И пишите в комментарии какие must have автоматизации есть в ваших процессах
#Kotlin #Ktor #Server
@kotlin_adept
#Kotlin #Ktor #Server
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Написал небольшую статью о рефакторинге архитектуры приложения с запутанной логикой.
По итогу получилось значительно упростить логику приложения и повысить надёжность. В этом помогли корутины, а точнее их не совсем стандартное применение.
Приятного чтения📖
#Architecture #Coroutines
@kotlin_adept
По итогу получилось значительно упростить логику приложения и повысить надёжность. В этом помогли корутины, а точнее их не совсем стандартное применение.
Приятного чтения
#Architecture #Coroutines
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegraph
Корутины — архитектурные помощники
Представьте, что у вас есть приложение, которое управляет пользовательскими данными. И вам пришла задача — отрефакторить подтверждение владения учётной записью для выполнения различных критически важных действий с аккаунтом пользователя. Таких действий может…
Использование null допустимо в domain типах?
Anonymous Poll
78%
Вполне, если очевидно, что подразумевается под отсутствием значения
22%
Нет,всегда использую sealed class, чтобы уйти от nullable типов
SwiftExport
Вчера вышел Kotlin 2.1, и мы стали еще на один шаг ближе к тому, чтобы отказаться от прослойки с Objective-C хедерами и использовать скомпилированный Kotlin-код напрямую в Swift😎
Но интересно даже не это — теперь, наконец, станет возможным разделять код на разные модули для Swift. Раньше все фичи, использующие KMP, могли обращаться к любой его части, а теперь это можно инкапсулировать.
🐱 Посмотреть пример кода можно здесь.
P.S. Я же очень жду возможность использования нескольких KMP библиотек в одном Swift проекте без создания umbrella модуля, чтобы была возможность переиспользовать рантайм Kotlin Native и общие библиотеки.
#KMP #Swift
@kotlin_adept
Вчера вышел Kotlin 2.1, и мы стали еще на один шаг ближе к тому, чтобы отказаться от прослойки с Objective-C хедерами и использовать скомпилированный Kotlin-код напрямую в Swift
Но интересно даже не это — теперь, наконец, станет возможным разделять код на разные модули для Swift. Раньше все фичи, использующие KMP, могли обращаться к любой его части, а теперь это можно инкапсулировать.
P.S. Я же очень жду возможность использования нескольких KMP библиотек в одном Swift проекте без создания umbrella модуля, чтобы была возможность переиспользовать рантайм Kotlin Native и общие библиотеки.
#KMP #Swift
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
Как подключить KMP в iOS проект без CocoaPods
Я задумался об этом еще в прошлом году и подключил всё, как описано в инструкции. Но как только в Xcode-проекте появились кастомные конфигурации, начало происходить нечто странное...
Проект продолжал компилироваться, но при этом все новые изменения в общем коде перестали отображаться в Xcode. А если почистить кеш, то и вовсе выводилась ошибка: "No such module Shared". Я поспрашивал в чате, сталкивался ли кто-то с подобной проблемой, но узнал лишь, что с CocoaPods всё работает хорошо. Поэтому я просто забил и перешел на CocoaPods, думая, что, если проблема есть, её наверняка исправят🔥
Однако CocoaPods стали deprecated, и вся наша iOS-команда уже давно мигрировала на SPM. Представьте лица iOS-разработчиков, к которым вы не только притащили KMP, но еще и хотите заставить их вернуться на CocoaPods👍
Поэтому я снова вернулся к этой задаче и, к моему удивлению, спустя год ничего не изменилось: проблема всё ещё присутствует даже на новых версиях. Я стал разбираться и выяснил, что по каким-то причинам Xcode визуально подтягивает только фреймворк по пути build/xcode-frameworks/debug. Но путь для сборки фреймворка меняется, как только появляются кастомные конфигурации, и отвечает за это переменная окружения CONFIGURATION.
Тут я подумал: а зачем нам вообще разделять на разные папки для каждой конфигурации? В любом случае каждую конфигурацию мы маппим в Debug или Release build type с помощью переменной KOTLIN_FRAMEWORK_BUILD_TYPE.
Поэтому я для себя сделал следующий workaround. В Build Phase в Xcode, где собирается Kotlin-фреймворк, нужно переопределить переменную окружения конфигурации:
Таким образом, для всех конфигураций, которые маппятся в Debug, всё будет работать, а для релизных конфигураций нам важнее успешная сборка, нежели подсветка кода в Xcode.
Официального ответа по этому issue я всё ещё не получил, поэтому поддержите лайком, чтобы команда JetBrains заметила и дала официальные рекомендации.
#KMP #Xcode #iOS
@kotlin_adept
Я задумался об этом еще в прошлом году и подключил всё, как описано в инструкции. Но как только в Xcode-проекте появились кастомные конфигурации, начало происходить нечто странное...
Проект продолжал компилироваться, но при этом все новые изменения в общем коде перестали отображаться в Xcode. А если почистить кеш, то и вовсе выводилась ошибка: "No such module Shared". Я поспрашивал в чате, сталкивался ли кто-то с подобной проблемой, но узнал лишь, что с CocoaPods всё работает хорошо. Поэтому я просто забил и перешел на CocoaPods, думая, что, если проблема есть, её наверняка исправят
Однако CocoaPods стали deprecated, и вся наша iOS-команда уже давно мигрировала на SPM. Представьте лица iOS-разработчиков, к которым вы не только притащили KMP, но еще и хотите заставить их вернуться на CocoaPods
Поэтому я снова вернулся к этой задаче и, к моему удивлению, спустя год ничего не изменилось: проблема всё ещё присутствует даже на новых версиях. Я стал разбираться и выяснил, что по каким-то причинам Xcode визуально подтягивает только фреймворк по пути build/xcode-frameworks/debug. Но путь для сборки фреймворка меняется, как только появляются кастомные конфигурации, и отвечает за это переменная окружения CONFIGURATION.
Тут я подумал: а зачем нам вообще разделять на разные папки для каждой конфигурации? В любом случае каждую конфигурацию мы маппим в Debug или Release build type с помощью переменной KOTLIN_FRAMEWORK_BUILD_TYPE.
Поэтому я для себя сделал следующий workaround. В Build Phase в Xcode, где собирается Kotlin-фреймворк, нужно переопределить переменную окружения конфигурации:
export CONFIGURATION=$KOTLIN_FRAMEWORK_BUILD_TYPE
cd "$SRCROOT/.."
./gradlew :shared:embedAndSignAppleFrameworkForXcode
Таким образом, для всех конфигураций, которые маппятся в Debug, всё будет работать, а для релизных конфигураций нам важнее успешная сборка, нежели подсветка кода в Xcode.
Официального ответа по этому issue я всё ещё не получил, поэтому поддержите лайком, чтобы команда JetBrains заметила и дала официальные рекомендации.
#KMP #Xcode #iOS
@kotlin_adept
Please open Telegram to view this post
VIEW IN TELEGRAM
5 причин порешать AdventOfCode
В этом году решил порешать рождественские задачки на любимом Kotlin, и это на самом деле интереснее и полезнее, чем кажется на первый взгляд. Особенно учитывая, что мне абсолютно никак не откликается LeetCode и нет никакого желания решать алгоритмические задачки, если я не собираюсь идти на собеседование.
Поэтому вот 5 причин, почему вам тоже стоит хотя бы раз попробовать AoC:
1. Вы решаете непривычные для себя задачи, тем самым развивая нестандартное мышление.
2. Даже если вы решаете на своем привычном языке, далеко не факт, что вы используете все его возможности. Вы сильно удивитесь, как одну и ту же задачу можно было решить намного элегантнее, посмотрев решения других участников.
3. Можно поорать с мемов на том же реддите. Решать задачи одновременно с коммьюнити гораздо интереснее!
4. Вы открываете для себя новые языки. Например, UIUA: на первый взгляд, синтаксис этого языка выглядит как ошибка кодировки символов, но задачи на нем решаются в пару строчек, тогда как на Kotlin придется написать в десятки раз больше кода.
5. Ну и просто заряжаетесь новогодним настроением, ведь у всех задач есть какой-никакой общий рождественский сюжет🔥
Ставьте 🎅, если тоже участвуете в AdventOfCode!
#AdventOfCode
В этом году решил порешать рождественские задачки на любимом Kotlin, и это на самом деле интереснее и полезнее, чем кажется на первый взгляд. Особенно учитывая, что мне абсолютно никак не откликается LeetCode и нет никакого желания решать алгоритмические задачки, если я не собираюсь идти на собеседование.
Поэтому вот 5 причин, почему вам тоже стоит хотя бы раз попробовать AoC:
1. Вы решаете непривычные для себя задачи, тем самым развивая нестандартное мышление.
2. Даже если вы решаете на своем привычном языке, далеко не факт, что вы используете все его возможности. Вы сильно удивитесь, как одну и ту же задачу можно было решить намного элегантнее, посмотрев решения других участников.
3. Можно поорать с мемов на том же реддите. Решать задачи одновременно с коммьюнити гораздо интереснее!
4. Вы открываете для себя новые языки. Например, UIUA: на первый взгляд, синтаксис этого языка выглядит как ошибка кодировки символов, но задачи на нем решаются в пару строчек, тогда как на Kotlin придется написать в десятки раз больше кода.
5. Ну и просто заряжаетесь новогодним настроением, ведь у всех задач есть какой-никакой общий рождественский сюжет
Ставьте 🎅, если тоже участвуете в AdventOfCode!
#AdventOfCode
Please open Telegram to view this post
VIEW IN TELEGRAM
Внезапно появилось желание адаптировать какой-нибудь KMP-проект под Аврору, и я решил узнать, как это сейчас можно сделать малой кровью. Почитал статью, посмотрел доклад, и в итоге на сегодняшний день ситуация выглядит следующим образом.
Если не брать во внимание экзотику вроде GraalVM и Kotlin Native, где нужного таргета нет почти ни в одной библиотеке, то остается только интероп через Kotlin JS и QML.
Почему-то я нигде не нашел примера с Compose для JS на Авроре. Возможно, на это есть причина, но, кажется, это наш выбор, так как почти все ключевые библиотеки поддерживают JS-таргет.
Идея очень проста: отображаем весь UI в WebView и вызываем платформенный API через колбэки с JavaScriptInterface.
За производительность, кажется, можно не переживать. По опыту, Compose в браузере работает даже быстрее, чем на iOS. Главная проблема Compose для JS — это большой бандл, но это не критично, если бандл поставляется вместе с приложением🧠
Главным камнем преткновения может стать то, что сейчас WebView в Авроре использует движок Gecko, однако в обозримом будущем планируется миграция на Chromium, и тогда все должно быть в порядке.
Очень хочется проверить эту теорию и запустить хотя бы сэмпл. Но нужного SDK под Apple-процессоры до сих пор нет в публичном доступе, так что пока ждем⌚️
#Aurora #KMP
Если не брать во внимание экзотику вроде GraalVM и Kotlin Native, где нужного таргета нет почти ни в одной библиотеке, то остается только интероп через Kotlin JS и QML.
Почему-то я нигде не нашел примера с Compose для JS на Авроре. Возможно, на это есть причина, но, кажется, это наш выбор, так как почти все ключевые библиотеки поддерживают JS-таргет.
Идея очень проста: отображаем весь UI в WebView и вызываем платформенный API через колбэки с JavaScriptInterface.
За производительность, кажется, можно не переживать. По опыту, Compose в браузере работает даже быстрее, чем на iOS. Главная проблема Compose для JS — это большой бандл, но это не критично, если бандл поставляется вместе с приложением
Главным камнем преткновения может стать то, что сейчас WebView в Авроре использует движок Gecko, однако в обозримом будущем планируется миграция на Chromium, и тогда все должно быть в порядке.
Очень хочется проверить эту теорию и запустить хотя бы сэмпл. Но нужного SDK под Apple-процессоры до сих пор нет в публичном доступе, так что пока ждем
#Aurora #KMP
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Mobius — канал конференции
#видеозаписи
Когда начинаешь публиковать записи докладов Mobius, с какой платформы логичнее приступать, Android или iOS?
С обеих сразу: в этот #МобильныйВторник открываем доклад, где речь про обе.
YouTube | VK Видео
Скачать презентацию с сайта Mobius
Когда начинаешь публиковать записи докладов Mobius, с какой платформы логичнее приступать, Android или iOS?
С обеих сразу: в этот #МобильныйВторник открываем доклад, где речь про обе.
YouTube | VK Видео
Скачать презентацию с сайта Mobius
Compose Multiplatform в проде
Хочу поделиться новостью: мы выпустили первое приложение, полностью написанное на Compose Multiplatform для iOS😌
Изначально приложение разрабатывалось только для Android, но использовался Kotlin-стек (Decompose, Ktor, SqlDelight, Koin) и обычный Jetpack Compose. Чтобы запустить его в каком-то виде на iOS, потребовалось всего 4 дня! Конечно, доведение до релиза заняло значительно больше времени, но всё равно это оказалось гораздо быстрее, чем полноценная разработка аналогичного проекта с нуля.
Что по итогам:
🟣 Compose в релизной версии вполне прилично работает, особенно на новых устройствах с поддержкой 120 Гц
🟣 Управление жестами удалось легко реализовать благодаря Decompose
🟣 Скролл подлагивает и не ощущается как нативный
🟣 BottomSheet, как всегда причиняет боль 😬
🟣 Есть некоторые баги с TextField
🟣 Некоторые контролы пришлось реализовать нативно, например, WebView, TimePicker и т.д.
Тем не менее, я уверен, что многие проблемы будут исправлены в будущем и уже сейчас Compose Multiplatform можно использовать в проектах, где плавность интерфейса не является критически важной👍
#iOS #Compose
Хочу поделиться новостью: мы выпустили первое приложение, полностью написанное на Compose Multiplatform для iOS
Изначально приложение разрабатывалось только для Android, но использовался Kotlin-стек (Decompose, Ktor, SqlDelight, Koin) и обычный Jetpack Compose. Чтобы запустить его в каком-то виде на iOS, потребовалось всего 4 дня! Конечно, доведение до релиза заняло значительно больше времени, но всё равно это оказалось гораздо быстрее, чем полноценная разработка аналогичного проекта с нуля.
Что по итогам:
Тем не менее, я уверен, что многие проблемы будут исправлены в будущем и уже сейчас Compose Multiplatform можно использовать в проектах, где плавность интерфейса не является критически важной
#iOS #Compose
Please open Telegram to view this post
VIEW IN TELEGRAM
Как подружить Web History и Compose resources
Недавно столкнулся с проблемой: после добавления поддержки Web History в проект с Compose для Web у меня перестали работать ресурсы, причём это происходило только на вложенных экранах.
Изначально я предположил, что проблема связана с настройками веб-сервера, но нет. В Compose для Web ресурсы загружаются по относительному пути. Это означает, что к текущему URL в браузере добавляется путь до ресурсов. Соответственно, если вы находитесь не на главной странице, то по такому пути ресурсы окажутся недоступными🫥
Посмотрел, что пишут в документации, но никаких рекомендаций там не дается на этот счет, что довольно странно. Поправить же проблему удалось следующим образом:
Добавляем этот код в функцию main в сорсете jsMain, и пути до ресурсов снова становятся корректными.
#Compose #JS #WEB
Недавно столкнулся с проблемой: после добавления поддержки Web History в проект с Compose для Web у меня перестали работать ресурсы, причём это происходило только на вложенных экранах.
Изначально я предположил, что проблема связана с настройками веб-сервера, но нет. В Compose для Web ресурсы загружаются по относительному пути. Это означает, что к текущему URL в браузере добавляется путь до ресурсов. Соответственно, если вы находитесь не на главной странице, то по такому пути ресурсы окажутся недоступными
Посмотрел, что пишут в документации, но никаких рекомендаций там не дается на этот счет, что довольно странно. Поправить же проблему удалось следующим образом:
configureWebResources {
resourcePathMapping { path -> "${location.origin}/$path" }
}
Добавляем этот код в функцию main в сорсете jsMain, и пути до ресурсов снова становятся корректными.
#Compose #JS #WEB
Please open Telegram to view this post
VIEW IN TELEGRAM
Интероп suspend и async функций
Ранее все suspend-функции в Kotlin превращались в обычные функции с completionHandler на стороне Swift, но начиная с Swift 5.5 появился интероп между корутинами в обе стороны. Однако пусть это не вводит вас в заблуждение: это всего лишь "сахар" в Swift, который преобразует коллбэки в асинхронные функции❗️
Соответственно, у вас будет работать базовый сценарий использования асинхронной функции, но на этом из хороших новостей всё:
❌ Запуск async-функции на Main-диспетчере не гарантирует выполнения на главном потоке в Swift.
❌ CancellationException не будет преобразовываться в CancellationError, соответственно, не будет работать кооперативная отмена корутин и есть риск получить work leak.
💡 Казалось бы, с этой проблемой может помочь библиотека SKIE, но и там не всё гладко. Она исправляет только интероп в одну сторону, когда мы вызываем suspend-функции из Swift-кода, но не в обратную.
Так что будьте осторожны с таким интеропом и следите за развитием полноценной поддержки в соответствующем issue.
#Coroutines #Kotlin #Swift
Ранее все suspend-функции в Kotlin превращались в обычные функции с completionHandler на стороне Swift, но начиная с Swift 5.5 появился интероп между корутинами в обе стороны. Однако пусть это не вводит вас в заблуждение: это всего лишь "сахар" в Swift, который преобразует коллбэки в асинхронные функции
Соответственно, у вас будет работать базовый сценарий использования асинхронной функции, но на этом из хороших новостей всё:
Так что будьте осторожны с таким интеропом и следите за развитием полноценной поддержки в соответствующем issue.
#Coroutines #Kotlin #Swift
Please open Telegram to view this post
VIEW IN TELEGRAM
Давайте тоже подведем итоги года. За этот год канал невероятно вырос по количеству подписчиков. Спасибо, что читаете, ставите лайки и делитесь постами — для меня это важно ❤️
Судя по количеству постов, очевидно, что я не самый продуктивный автор, но стараюсь делать уникальный и, надеюсь, полезный контент. Если у вас есть пожелания, какие посты вы хотели бы видеть чаще в следующем году, смело пишите в комментариях💬
И всех с наступающим Новым годом🚗
Судя по количеству постов, очевидно, что я не самый продуктивный автор, но стараюсь делать уникальный и, надеюсь, полезный контент. Если у вас есть пожелания, какие посты вы хотели бы видеть чаще в следующем году, смело пишите в комментариях
И всех с наступающим Новым годом
Please open Telegram to view this post
VIEW IN TELEGRAM
Представьте, что у вас есть список карточек, и на каждой из них отображается информация, которая обновляется в реальном времени.
Как правило, логикой обновления карточек занимается ViewModel экрана, однако это не всегда удобно. Что, если у каждой карточки будет собственный компонент логики, который будет подписываться на данные и самостоятельно изменять своё состояние?
Проблема здесь в том, что необходимо отменять подписку и освобождать ресурсы, если карточка больше не видна на экране.
🌳 Решить эту задачу можно с помощью библиотеки Decompose. Однако стандартные методы навигации из коробки не подходят. Наиболее близкий по смыслу — это ChildPages, который преимущественно используется в связке с ViewPager. Тем не менее, он отличается от ленивого списка.
Поэтому можно создать собственный тип навигации для использования с LazyList, который корректно управляет жизненным циклом компонентов:
🔵 Видимые компоненты будут находиться в состоянии Resumed.
🔸 Компоненты, ближайшие к видимым, — в состоянии Started.
🔸 Остальные — в состоянии Created или Destroyed.
Таким образом, получилось декомпозировать логику и избавиться от бойлерплейта, связанного с отменой подписок.
Пример и реализацию кастомного механизма навигации можно посмотреть здесь🐱
За решение спасибо моему коллеге Евгению Мельцайкину👏
Как правило, логикой обновления карточек занимается ViewModel экрана, однако это не всегда удобно. Что, если у каждой карточки будет собственный компонент логики, который будет подписываться на данные и самостоятельно изменять своё состояние?
Проблема здесь в том, что необходимо отменять подписку и освобождать ресурсы, если карточка больше не видна на экране.
Поэтому можно создать собственный тип навигации для использования с LazyList, который корректно управляет жизненным циклом компонентов:
Таким образом, получилось декомпозировать логику и избавиться от бойлерплейта, связанного с отменой подписок.
Пример и реализацию кастомного механизма навигации можно посмотреть здесь
За решение спасибо моему коллеге Евгению Мельцайкину
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Самая странная документация
Я, конечно, видел многое: когда у open-source библиотек документация отсутствовала совсем, была неполной или, наоборот, даже имела свой сайт с кучей классных примеров.
Но тут я столкнулся с gradle-плагином KMMBridge от известных ребят из Touchlab. Плагин предназначен для публикации KMP-фреймворка и его подключения через CocoaPods или SPM в iOS-проекте.
Итак, на GitHub никакой документации нет — всё на сайте, что, в целом, хорошо, идём туда. Прошерстив сайт, я понял, что это единственный плагин, в котором не написано, как его подключать. Как думаете, есть ли там информация о gradle-тасках, которые регистрирует плагин? Ответ очевиден👎
Тут может возникнуть логичный вопрос: а что вообще есть?
Они предлагают создать GitHub-проект из шаблона, где всё за тебя настроят, включая GitHub Actions🤡
Супер странное решение, как будто все будут стартовать проект с этого плагина. Ага, конечно.
В итоге пришлось разбираться в шаблоне и исходном коде плагина, чтобы понять, как его использовать. И всё равно пришлось делать форк, так как они не предусмотрели возможность менять endpoint при загрузке в S3-хранилище.
В целом, плагин довольно полезный: с ним можно удобно шарить общий код с iOS, находясь в разных репозиториях. Но такой подход к документации явно может отпугнуть большинство пользователей.
А от какой документации вы кринжанули больше всего?
Я, конечно, видел многое: когда у open-source библиотек документация отсутствовала совсем, была неполной или, наоборот, даже имела свой сайт с кучей классных примеров.
Но тут я столкнулся с gradle-плагином KMMBridge от известных ребят из Touchlab. Плагин предназначен для публикации KMP-фреймворка и его подключения через CocoaPods или SPM в iOS-проекте.
Итак, на GitHub никакой документации нет — всё на сайте, что, в целом, хорошо, идём туда. Прошерстив сайт, я понял, что это единственный плагин, в котором не написано, как его подключать. Как думаете, есть ли там информация о gradle-тасках, которые регистрирует плагин? Ответ очевиден
Тут может возникнуть логичный вопрос: а что вообще есть?
Они предлагают создать GitHub-проект из шаблона, где всё за тебя настроят, включая GitHub Actions
Супер странное решение, как будто все будут стартовать проект с этого плагина. Ага, конечно.
В итоге пришлось разбираться в шаблоне и исходном коде плагина, чтобы понять, как его использовать. И всё равно пришлось делать форк, так как они не предусмотрели возможность менять endpoint при загрузке в S3-хранилище.
В целом, плагин довольно полезный: с ним можно удобно шарить общий код с iOS, находясь в разных репозиториях. Но такой подход к документации явно может отпугнуть большинство пользователей.
А от какой документации вы кринжанули больше всего?
Please open Telegram to view this post
VIEW IN TELEGRAM
Я снова принял участие в программном комитете конференции Podlodka Android Crew.
И нам нужна ваша помощь в выборе темы нового сезона. Какая из предложенных тем вам ближе, и вы бы хотели посетить сезон, посвящённый ей?
#️⃣ Compose: 3 года в продакшене
#️⃣ Тесты 360
#️⃣ Карьера Android-разработчика
Заполните, пожалуйста, форму. Среди участников, заполнивших форму, мы разыграем проходку на конференцию.
И нам нужна ваша помощь в выборе темы нового сезона. Какая из предложенных тем вам ближе, и вы бы хотели посетить сезон, посвящённый ей?
Заполните, пожалуйста, форму. Среди участников, заполнивших форму, мы разыграем проходку на конференцию.
Please open Telegram to view this post
VIEW IN TELEGRAM
Из раза в раз Android-разработчики страдают при обновлении зависимостей в поиске совместимых версий, и мы не стали исключением. Недавно нам понадобилось обновить версию библиотеки Coil для устранения проблем с бинарной совместимостью. Однако новая версия библиотеки подтянула за собой Kotlin 2.1.0, из-за чего наш Android Gradle Plugin начал выдавать множество предупреждений, связанных с R8, и предлагал заглянуть в таблицу совместимых версий. Стоит ли говорить, что в этой таблице новой версии Kotlin не оказалось 🫥
Ну что ж, обновляем AGP до последней версии в надежде, что всё заработает. Действительно, предупреждения исчезли, но минификация перестала работать😬
Что же произошло
В версии AGP 8.4.2 изменили механизм работы R8.
Как было раньше
Сначала собирались все модули, затем выполнялась минификация каждого модуля
Как стало сейчас
Теперь минификация выполняется отдельно для каждого модуля сразу после его сборки. Из-за этого R8 считает, что код в модуле никем не используется, и просто удаляет его!
Как исправить
Правильным решением будет оставить флаг isMinifyEnabled только в application модуле. Поскольку он зависит от всех остальных модулей в приложении, минификация будет выполняться только после сборки всех модулей. Это обеспечит корректную работу минификации как для app-модуля, так и для остальных модулей.
Таким образом, оставив минификацию только для app-модуля, мы не только исправили проблему, но и ускорили сборку релизной версии, так как теперь минификация запускается только один раз.
#Android #Gradle #R8
Ну что ж, обновляем AGP до последней версии в надежде, что всё заработает. Действительно, предупреждения исчезли, но минификация перестала работать
Что же произошло
В версии AGP 8.4.2 изменили механизм работы R8.
Как было раньше
Сначала собирались все модули, затем выполнялась минификация каждого модуля
Как стало сейчас
Теперь минификация выполняется отдельно для каждого модуля сразу после его сборки. Из-за этого R8 считает, что код в модуле никем не используется, и просто удаляет его!
Как исправить
Правильным решением будет оставить флаг isMinifyEnabled только в application модуле. Поскольку он зависит от всех остальных модулей в приложении, минификация будет выполняться только после сборки всех модулей. Это обеспечит корректную работу минификации как для app-модуля, так и для остальных модулей.
Таким образом, оставив минификацию только для app-модуля, мы не только исправили проблему, но и ускорили сборку релизной версии, так как теперь минификация запускается только один раз.
#Android #Gradle #R8
Please open Telegram to view this post
VIEW IN TELEGRAM