Переход с Dagger2 на Hilt в многомодульном проекте
Пошаговое руководство по миграции с Dagger
многомодульного Hilt
проекта.
Структура проекта
Для визуализации проекта он содержит несколько модулей NetworkModule, StorageModule, CommonModule, FeatureModule и т. д. В реальных проектах может быть намного больше модулей, но мы ограничиваемся следующими модулями.

Стратегия миграции
Мы хотим полностью перейти Dagger
на, Hilt
но на практике нам нужен поэтапный подход, при котором мы сначала перенесем наш app
проект, Hilt
а затем другие модули, что означает, что Dagger
они Hilt
должны работать параллельно в течение некоторого времени, пока не будет выполнена полная миграция.
Версии
Эта история выполнит миграцию с Dagger 2.24
на Hilt 2.45
.
Содержание
- Конфигурация/Подготовка
- Перенос компонента приложения и синглтона
- Перенести класс приложения
- Перенос класса активности
- Перенести фрагмент
- Перенос ViewModel
- Очистка после миграции
- Резюме и выводы
Для интеграции добавьте следующие зависимости в файл Hilt
приложения Gradle.build.gradle
Также настройте kapt
для установки correctErrorType true
в build.gradle
файле
dependencies {
implementation 'com.google.dagger:hilt-android:2.45'
kapt 'com.google.dagger:hilt-compiler:2.45'
}
// Allow references to generated code
kapt {
correctErrorTypes = true
}
plugins {
// other plugins
id 'com.google.dagger.hilt.android' version '2.45' apply false
}
plugins {
// other plugins
id 'com.google.dagger.hilt.android'
}
android {
....
}
Перенос компонента приложения
Dagger включает Singleton
Component
в себя все модули Dagger, созданные в приложении или других модулях проекта, и обычно это делается в AppComponent
классе, созданном для Dagger
.
Давайте посмотрим на текущий файл AppComponent.kt
Для миграции Singleton
Component
нам нужно установить каждый модуль, например NetworkModule , StorageModule и т. д., в SingletonComponent
for Hilt
, вы можете сделать это, аннотировав все эти отдельные модули с помощью @InstallIn(SingletonComponent::class)
Но если у вас много модулей, изменение их всех сразу не будет хорошей идеей, но вы можете создайте AggregatedModule , который будет аннотирован @InstallIn(SingletonComponent::class)
и включает все эти Dagger
модули, аннотированные с помощью @Module(includes = [ <all of these modules > ])
.
Запустите проект, он выдаст ошибку
Ошибка DisableModuleHasInstallInCheck
После запуска проект Hilt
попытается найти @InstallIn
аннотацию для каждого модуля, входящего в AggregatedModule
аннотированный файл @Module
. Hilt
вызовет ошибку, если найдет модуль, который не аннотирован с помощью @Install
Поскольку мы не аннотировали каждый модуль, @InstallIn
потому что мы находимся в середине миграции, мы можем отключить эту ошибку, используя следующий флаг
-Adagger.hilt.disableModulesHaveInstallInCheck=true
.
вы можете указать на уровне приложения build.gradle
, как показано ниже, но мы должны удалить этот флаг после завершения миграции.
defaultConfig {
//TODO: remove this after migration to Hilt
javaCompileOptions {
annotationProcessorOptions {
arguments["dagger.hilt.disableModulesHaveInstallInCheck"]="true"
}
}
}
Перенести класс приложения
Чтобы добавить Hilt в приложение, давайте аннотируем Application
класс с помощью @HiltAndroidApp
. Вы должны удалить @Component
и @Component.Builder
которые присутствовали в AppComponent
классе, как указано выше.
Если вы Application
расширяете DaggerApplication
или реализуете, HasAndroidInjector
вам все равно нужно сохранить некоторый код, как показано ниже, в обоих этих случаях. Это должно поддерживать оба Dagger
и Hilt
параллельно, пока вся миграция не будет завершена.
Если ваши Application
расширения из DaggerApplication
вашего класса приложения будут выглядеть так.
И если ваши Application
инструменты HasAndroidInjector
, ваше приложение должно выглядеть так
Как только вся миграция будет завершена, вам нужно будет удалить такой код из вашего Application
класса, и ваш код Application
будет выглядеть так, как показано ниже. (Но это будет один из последних шагов, пожалуйста, не делайте этого сейчас)
Запустите проект, он должен успешно собрать ваш проект, и приложение должно запуститься без исключений во время выполнения.
Перенос класса активности
Dagger позволяет @ContributesAndroidInjector
указать любое действие/фрагмент в качестве участника для Android Injector, в нашем проекте, который выполняется в MainActivityModule
, один из модулей, включенных вAggregatedModule
MainActivityModule
так выглядит до миграции
MainActivity
так выглядит до миграции
Чтобы перейти MainActivity
на Hilt
, мы полностью избавимся от MainActivityModule
класса модуля и добавим аннотацию @AndroidEntryPoint
для MainActivity
. Поскольку наш MainActivity
также расширяется, DaggerAppCompatActivity
нам нужно расширить нашу деятельность из соответствующего, AppCompatActivity
поэтому после миграции наша MainActivity
будет выглядеть так, как показано ниже.
Запустите свой проект, он должен быть успешно MainActivity
перенесен в Hilt
Перенести фрагмент/представление/BroadcastReceiver
Миграция любого фрагмента в Hilt
будет выполняться с теми же шагами, что и для миграции MainActivity
в Hilt. Шаги ниже
- Удалите код, в котором вы аннотируете свой фрагмент, который,
@ContributesAndroidInjector
вероятно, будет модулем. - Удалить модуль, из
SingletonComponent
которого обрабатывался@ContributesAndroidInjector
ваш фрагмент - Аннотируйте свой фрагмент с помощью
@AndroidEntryPoint
- если ваш фрагмент расширен,
DaggerFragment
вам нужно расширить свой фрагмент изFragment
класса
Перенос ViewModel
Миграция ViewModel требует некоторых шагов.
Сначала аннотируйте свою модель представления с помощью@HiltViewModel
Для FeatureViewModel
внедрения Hilt
мы будем использовать расширение фрагмента, viewModels()
указанное в зависимости расширения фрагмента, которую мы добавим в соответствующий build.gradle
файл, как показано ниже.
implementation "androidx.fragment:fragment-ktx:1.5.6"
Теперь удалите соответствующие @Bind
, @IntoMap
и @ViewModelKey
привязки, FeatureViewModel
которые мы использовали для Dagger.
В кинжале для внедрения ViewModel у нас также будет lateinit var
свойство, которое будет использоваться injected
во время выполнения, используя некоторые из них ViewModelFactory
, которые также больше не требуются, поэтому вы можете удалить ViewModelModule
и ViewModelProviderFactory
связанный код, если на кинжале нет другой ViewModel/Fragment.
Запустите свой проект, он должен быть успешно Fragment and ViewModel
перенесен в Hilt
Перенос других модулей.
До сих пор мы мигрировали Components
// Modules
/ Activity
в Fragment
модуль приложения. Но сейчас нам нужно перенести другие модули. Мы будем переходить по одному модулю за раз и полностью переносить его в Hilt, выполнив следующие шаги.
- Добавить
Hilt
зависимость вbuild.gradle
файл модуля - Аннотируйте каждую
@Module
аннотацией@InstallIn
. - Удалите
@JvmStatic
аннотацию для каждой@Provide
аннотации, если она у вас есть, потому что она больше не требуется вHilt
- Аннотируйте свой
Fragment
/Activity
с@AndroidEntryPoint
и удалите соответствующий@ContributesAndroidInjector
- Перенесите ваши ViewModels, аннотируя их
@HiltViewModel
, и используйте расширение фрагментаviewModels()
для внедрения этих моделей представлений. - Продолжайте удалять все те модули, которые больше не потребуются в
AggregatedModule
.AggregatedModule
мы создали выше в нашем первом шаге.
После переноса каждого модуля проекта в Hilt
. Нужно время на уборку
- Удалить disableModuleInstallInCheck = true, который мы добавили в начале на уровне приложения или любом другом,
build.gradle
и удалить@DisableInstallInCheck
аннотацию, если она была добавлена к любому@Module
defaultConfig {
//TODO: remove this after migration to Hilt
javaCompileOptions {
annotationProcessorOptions {
arguments["dagger.hilt.disableModulesHaveInstallInCheck"]="true"
}
}
}
4. Удалите все Dagger
зависимости во всех ваших модулях.
Запустите свой проект, он должен быть успешно запущен, ваш проект полностью перенесен в Hilt
Резюме и выводы
Общий обзор изменений кода после миграции будет выглядеть так
- Все аннотации кода
@Component
/@Component.Builder
/@Component.Factory
/@ContributesAndroidInjector
/@ViewModelKey
были бы удалены - Все ваши ViewModels должны быть аннотированы с помощью
@HiltViewModel
- Все
@Module
классы должны быть аннотированы@InstallIn
аннотацией - Фрагменты/действия/представление/служба должны быть аннотированы с помощью
@AndroidEntryPoint
- Класс приложения должен быть аннотирован с помощью
@HiltAndroidApp
AppComponent
и соответствующий код должен быть удален@JvmStatic
аннотации внутри модулей Hilt больше не должны существовать
- Внедрение зависимостей с помощью Hilt
- Переход на официальную документацию Hilt
Не забудьте подписаться и , если вам понравилось :)
— — — — — — — — — — —
Гитхаб | Линкедин | Твиттер
Повышение уровня кодирования
Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:
- Хлопайте за историю и подписывайтесь на автора
- Смотрите больше контента в публикации Level Up Coding
- Бесплатный курс собеседования по программированию ⇒ Посмотреть курс
- Подписывайтесь на нас: Твиттер | Линкедин | Новостная рассылка