Вышел Dagger 2.50
👉 Готовятся к поддержке
👉 Значение флага
#dagger
👉 Готовятся к поддержке
jakarta.inject.Provider 👉 Значение флага
-Adagger.explicitBindingConflictsWithInject теперь выступленое в enabled по умолчанию#dagger
❤5👍2
Обновление Android Jetpack:
🎉 Hilt 1.2.0 - добавлена поддержка Assited Inject в
🎉 Test Uiautomator 2.3.0 - поддержка множества дисплеев, новые селекторы, кастомные Condition позволят реализовать собственные условия ожидания
👉 Benchmark 1.3.0-alpha01 - множество улучшений и исправления багов
👉 Lifecycle 2.8.0-alpha02 - ViewModel переписалин на Kotlin, Lifecycle API стало мультиплатформенным, новые API
👉 Lint 1.0.0-alpha01 - Lint проверки для авторов Gradle плагинов
Больше подробностей тут
#jetpack #jetpackupdate #dagger #hilt
🎉 Hilt 1.2.0 - добавлена поддержка Assited Inject в
hiltViewModel() and hiltNavGraphViewModels()🎉 Test Uiautomator 2.3.0 - поддержка множества дисплеев, новые селекторы, кастомные Condition позволят реализовать собственные условия ожидания
👉 Benchmark 1.3.0-alpha01 - множество улучшений и исправления багов
👉 Lifecycle 2.8.0-alpha02 - ViewModel переписалин на Kotlin, Lifecycle API стало мультиплатформенным, новые API
dropUnlessResumed() и dropUnlessStarted()👉 Lint 1.0.0-alpha01 - Lint проверки для авторов Gradle плагинов
Больше подробностей тут
#jetpack #jetpackupdate #dagger #hilt
🔥28👍8❤1
В Hilt 1.2.0 теперь можно делать такое c ViewModel
Для тех кто не знаком с Assisted Injection читайте документацию Dagger
#hilt #di #dagger
Для тех кто не знаком с Assisted Injection читайте документацию Dagger
#hilt #di #dagger
🔥65👍12❤2🎉2
Вышел Dagger 2.51:
👉
👉 Новая фича позволит корректно делать обфускацию ViewModel с аннотацией
👉 Аннотация @SkipTestInjection для пропуска инжекта в Hilt Android тестах
🛠 Исправление багов
#dagger
👉
@LazyClassKey - аннотация с поддержкой использования классов в Map Key, но в отличие от @ClassKey класс будет загружаться отложено👉 Новая фича позволит корректно делать обфускацию ViewModel с аннотацией
@HiltViewModel👉 Аннотация @SkipTestInjection для пропуска инжекта в Hilt Android тестах
🛠 Исправление багов
#dagger
👍24🔥1
Статья (3м) с описанием как упростить inject параметров с помощью библиотеки автора Anvil Utils
#anvil #dagger #di
#anvil #dagger #di
🔥10👍3
Передача данных между фрагментом и BottomSheetDialogFragment с использованием Dagger и Navigation Component (2м) - статья с рецептом с упором на код
#fragment #dagger #jetpack #di
#fragment #dagger #jetpack #di
43👎49🤔13👍6😱5
Media is too big
VIEW IN TELEGRAM
Обзор библиотеки Kotlin Inject - DI для KMP, API которого аналогично Dagger. В видео происходит демонстрация возможностей, сравнение с другими DI и личное мнение о том стоит ли использовать эту библиотеку в проде.
Видео доступно платным подписчикам на Boosty и через Tribute бота в Telegram
#видео #kmp #dagger #di #koin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24👍6 5
Автор Koin поделился результатами замерами скорости работы Koin и Hilt. Для этого взяли оригинальную версию приложения Now In Android и собственную с миграцией на Koin.
Тест делался через простой замер времени от и до, автор намеренно отказался от Jetpack Benchmark, который обеспечивает прогрев и стабильность результатов. Такой подход у меня вызывает вопросы. Мне также было бы интересно увидеть замеры после оптимизации кода через R8
Результаты на картинке, подробности в статье, а дальше уже всё решать вам.
UPD В комментариях уже накопали как выкрутили замеры в пользу Koin
#di #koin #dagger #benchmark
Тест делался через простой замер времени от и до, автор намеренно отказался от Jetpack Benchmark, который обеспечивает прогрев и стабильность результатов. Такой подход у меня вызывает вопросы. Мне также было бы интересно увидеть замеры после оптимизации кода через R8
Результаты на картинке, подробности в статье, а дальше уже всё решать вам.
UPD В комментариях уже накопали как выкрутили замеры в пользу Koin
#di #koin #dagger #benchmark
👍20 2
Вышел Dagger 2.53 c breaking changes для Kotlin
👉 Все
👉 Обязательно использование
👉
👉 Удалена поддержка Java 7
‼️ Ничего полезного в Dagger не добавляют уже давно, так что сидите на той версии что вас устраивает и работает.
#dagger #di
👉 Все
Binds теперь потребуют объявления с nullable типами 👉 Обязательно использование
JvmSuppressWildcards в Multibinding Map для generic типа значения👉
Binds методы теперь не могут использовать Scope, когда они делегирует @Produces имплементации👉 Удалена поддержка Java 7
‼️ Ничего полезного в Dagger не добавляют уже давно, так что сидите на той версии что вас устраивает и работает.
#dagger #di
👍15🔥11🤯6 2
Вышел Dagger 2.54
Релиз который мы заслужили - переделки и багфиксы. Зачем вообще обновлять Dagger я не понимаю 😞
#dagger #di
Релиз который мы заслужили - переделки и багфиксы. Зачем вообще обновлять Dagger я не понимаю 😞
#dagger #di
🤯15👍9
🤯 Не нужно делать инжект всех зависимостей в конструктор
Встретил код в проекте:
sendDataUseCase не нужен сразу при создании объекта, а нужен только если пользователь нажмёт на кнопку "Send" в UI, что может и не произойти. Так как эта зависимость нужна в конструкторе, то при получении в DI будет сразу происходить создание этой зависимости, что приводит к ненужной нагрузке.
Я рекомендую делать отложенное получение зависимостей с помощью механизма Provider или Lazy. Первый будет ходить за зависимостью в граф каждый раз, а второй - при первом обращении и сохранит её.
Если вы используете Koin на момент написания поста (актуальная версия 4.0), делать отложенный инжект в конструктор возможности нет:
Результат оптимизации
✅ более быстрый старт экранов (зависит от сложности графов)
✅ уменьшение расхода памяти
❌ KOIN потеря явной зависимости в конструкторе. Мне бы очень хотелось увидеть аналог Provider и Lazy в Koin через конструктор, но пока приходится делать свои обертки 😔
#dagger #di #лучшиепрактики
Встретил код в проекте:
class MyViewModel(
...
private val sendDataUseCase: SendDataUseCase,
...
): ViewModel() {
// Вызывается, когда пользователь в UI нажмёт на "Send"
fun onSendClicked(...) {
viewModelScope.launch {
sendDataUseCase.invoke(...) // либо sendDataUseCase(...)
}
}
}
sendDataUseCase не нужен сразу при создании объекта, а нужен только если пользователь нажмёт на кнопку "Send" в UI, что может и не произойти. Так как эта зависимость нужна в конструкторе, то при получении в DI будет сразу происходить создание этой зависимости, что приводит к ненужной нагрузке.
Я рекомендую делать отложенное получение зависимостей с помощью механизма Provider или Lazy. Первый будет ходить за зависимостью в граф каждый раз, а второй - при первом обращении и сохранит её.
// При использовании Dagger или Hilt
class MyViewModel(
...
private val sendDataUseCase: javax.inject.Provider<SendDataUseCase>, // или dagger.Lazy
...
): ViewModel() {
fun onSendClicked(...) {
viewModelScope.launch {
sendDataUseCase.get()
.invoke(...)
}
}
}
Если вы используете Koin на момент написания поста (актуальная версия 4.0), делать отложенный инжект в конструктор возможности нет:
// При использовании Koin
class MyViewModel(): ViewModel() {
// отложенное получение зависимости в Koin
private val sendDataUseCase: SendDataUseCase by inject()
fun onSendClicked(...) {
viewModelScope.launch {
// аналог Provider - получение зависимости каждый раз из графа
val sendDataUseCase: SendDataUseCase = getKoin().get()
sendDataUseCase.invoke(...)
}
}
}
Результат оптимизации
✅ более быстрый старт экранов (зависит от сложности графов)
✅ уменьшение расхода памяти
❌ KOIN потеря явной зависимости в конструкторе. Мне бы очень хотелось увидеть аналог Provider и Lazy в Koin через конструктор, но пока приходится делать свои обертки 😔
#dagger #di #лучшиепрактики
🔥65👍21❤4
В статье рассказывается в чем сложность с обработкой одноразовых событий, которые надо передать из ViewModel в UI.
Автор рассматривает способ через callback интерфейс в конструкторе ViewModel
@HiltViewModel
class MyViewModel @Inject constructor(
// inject the interface
private val toastMessages: ToastMessages,
) : ViewModel() {
fun doSomething() {
viewModelScope.launch {
try {
// execute async operation here
} catch (e: CustomException) {
// initiate a one-off event
toastMessages.showToast(e.localizedMessage)
}
}
}
}
🔗 Альтернативная ссылка на статью
#android #viewmodel #dagger #hilt
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Как найти неиспользуемые зависимости в Dagger Component (EN,11м)
С помощью Dagger SPI автор написал анализатор графа Dagger c целью поиска неиспользуемых зависимостей и описал подход в статье. Также подход можно использовать для визуализации графа зависимостей, считать разные метрики графа и пр.
🐱 Исходный код на GitHub
🔗 Альтернативная ссылка
#dagger #di #opensource
С помощью Dagger SPI автор написал анализатор графа Dagger c целью поиска неиспользуемых зависимостей и описал подход в статье. Также подход можно использовать для визуализации графа зависимостей, считать разные метрики графа и пр.
🔗 Альтернативная ссылка
#dagger #di #opensource
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍26
🤯 Вышел Dagger 2.57 и из полезных изменений там... НИЧЕГО. Просто работают под капотом. Может над поддержкой KSP, может еще над чем
Вам нужен Dagger?
#dagger #di
Вам нужен Dagger?
#dagger #di
🤔38👍16🤯5
#dagger #hilt #koin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍6❤4
Одна из частых ошибок при использовании DI — получать все зависимости из графа сразу (например, в конструкторе класса).
Так делать не стоит 😬
Получение зависимости из графа — это каскадный процесс, и он должен выполняться только в момент использования.
Поэтому я всегда рекомендую инжектить зависимости для Dagger/Hilt через Lazy (не путайте с kotlin.Lazy) или Provider.
class ViewModel @Inject constructor(
// Зависимость получается из графа сразу при создании
private val useCase: DataUseCase,
// Получаем зависимость из графа каждый раз при обращении Provider.get()
private val useCaseFactory: Provider<DataUseCase>,
// Получаем зависимость из графа при первом обращении
// и затем она кэшируется в Lazy объекте
private val useCaseLazy: Lazy<DataUseCase>,
)
💡 Чтобы перейти на Lazy без боли в существующем коде — можно использовать делегаты свойств в Kotlin:
// Вариант использования без Lazy
class ViewModel @Inject constructor(
private val useCase: DataUseCase
)
// Миграция на Lazy без потери API совместимости
class ViewModel @Inject constructor(
useCaseFactory: Lazy<DataUseCase>,
) {
private val useCase: DataUseCase by useCaseFactory
}
И небольшой хелпер, чтобы это работало красиво 👇
// Функция расширения для использования property делегата
operator fun <T> Lazy<T>.getValue(thisRef: T, property: KProperty<*>): T = get()
Таким образом, вы снижаете нагрузку на DI граф, откладываете инициализацию и избегаете ненужных каскадов при старте компонентов.
#di #dagger #hilt #лучшиепрактики
Please open Telegram to view this post
VIEW IN TELEGRAM
👍88🤔26❤19🤯11
🚀 Cash App перевел Android-приложение на Metro — новый DI фреймворк для Kotlin
Команда Cash App (Block) успешно мигрировала своё Android-приложение с Anvil/Dagger на Metro — современный фреймворк для dependency injection, разработанный Zac Sweers.
Почему перешли на Metro?
- Скорость сборки — ускорение инкрементальных сборок на ~60%
- Поддержка Kotlin K2 — возможность использовать новейший компилятор Kotlin
- Упрощение стека — отказ от kapt и Java-ориентированных инструментов
- Современный подход — Kotlin-first дизайн и улучшенный DX
- Более строгая валидация DI-графа
- Улучшена безопасность типов (нуллабельность)
- Поддержка KMP
📊 Результаты по скорости сборки:
- Инкрементальные сборки → ускорение на 58-60%
- Чистые сборки → ускорение на 17%
- ABI-изменения → сборка за 11.9s вместо 28.8s
Миграция 1500 модулей проводилась постепенно с двойной поддержкой двух DI фреймворков для безопасного перехода. В зависимости от настройки Gradle менялся DI и генерация кода.
Впервые вижу подход, когда был описан граф для 2 разных DI с целью постепенной миграции. Миграцию с Koin на Metro так не сделать, но вот с Koin Annotations на Metro вполне может получится.
#DI #KMP #Dagger #Metro #Android #AndroidDev #Anvil
Команда Cash App (Block) успешно мигрировала своё Android-приложение с Anvil/Dagger на Metro — современный фреймворк для dependency injection, разработанный Zac Sweers.
Metro — это compile-time DI фреймворк, вдохновленный Dagger и Anvil, но реализованный как Kotlin compiler plugin. Он Kotlin-first, поддерживает K2 и работает значительно быстрее традиционных решений. Вобрал в себя всё лучшее от Dagger, Anvil и Kotlin-Inject
Почему перешли на Metro?
- Скорость сборки — ускорение инкрементальных сборок на ~60%
- Поддержка Kotlin K2 — возможность использовать новейший компилятор Kotlin
- Упрощение стека — отказ от kapt и Java-ориентированных инструментов
- Современный подход — Kotlin-first дизайн и улучшенный DX
- Более строгая валидация DI-графа
- Улучшена безопасность типов (нуллабельность)
- Поддержка KMP
📊 Результаты по скорости сборки:
- Инкрементальные сборки → ускорение на 58-60%
- Чистые сборки → ускорение на 17%
- ABI-изменения → сборка за 11.9s вместо 28.8s
Миграция 1500 модулей проводилась постепенно с двойной поддержкой двух DI фреймворков для безопасного перехода. В зависимости от настройки Gradle менялся DI и генерация кода.
Впервые вижу подход, когда был описан граф для 2 разных DI с целью постепенной миграции. Миграцию с Koin на Metro так не сделать, но вот с Koin Annotations на Metro вполне может получится.
#DI #KMP #Dagger #Metro #Android #AndroidDev #Anvil
👍43🔥18❤5👎1