Внедрение зависимостей с Hilt
Упростите управление зависимостями с помощью Hilt. Используйте @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides и области @Singleton.
«Внедрение зависимостей с Hilt» — бесплатный урок Android Academy на CoddyKit. Это урок 6 из 6. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 6 уроков всего.
Что такое внедрение зависимостей?
Внедрение зависимостей (DI) означает передачу объекту всего необходимого вместо самостоятельного создания зависимостей.
Без DI класс создаёт собственные зависимости — это приводит к тесной связанности и усложняет тестирование. При использовании DI зависимости внедряются извне — классы слабо связаны, их легко тестировать и заменять.
Ручное DI и Hilt
Ручное DI работает, но при масштабировании становится неудобным:
// Manual DI — you create and pass everything:
val db = AppDatabase.getInstance(context)
val dao = db.userDao()
val repo = UserRepository(dao)
val factory = UserViewModel.Factory(repo)
val viewModel = ViewModelProvider(this, factory)[UserViewModel::class.java]
// With Hilt:
// Just annotate, Hilt does the wiring
@HiltViewModel
class UserViewModel @Inject constructor(private val repo: UserRepository) : ViewModel()Добавление Hilt
Добавьте Hilt в свой проект:
// project/build.gradle:
buildscript {
dependencies {
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.51'
}
}
// app/build.gradle:
plugins {
id 'com.google.dagger.hilt.android'
id 'kotlin-kapt'
}
dependencies {
implementation 'com.google.dagger:hilt-android:2.51'
kapt 'com.google.dagger:hilt-android-compiler:2.51'
}@HiltAndroidApp
Пометьте класс Application аннотацией @HiltAndroidApp. Это точка входа в иерархию компонентов Hilt:
@HiltAndroidApp
class MyApp : Application()
// Also register in AndroidManifest.xml:
// <application android:name=".MyApp" ...>@AndroidEntryPoint
Добавьте @AndroidEntryPoint к Activity, Fragment и Service, которым требуются внедряемые зависимости:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
analytics.logEvent("app_open")
}
}
@AndroidEntryPoint
class HomeFragment : Fragment() {
// Fragment's parent Activity must also be @AndroidEntryPoint
}@Inject — внедрение через конструктор
Пометьте конструктор аннотацией @Inject, чтобы указать Hilt, как создавать класс. Hilt автоматически разрешит все параметры:
class UserRepository @Inject constructor(
private val userDao: UserDao,
private val apiService: ApiService
) {
suspend fun getUsers() = userDao.getAll()
suspend fun syncFromNetwork() {
val users = apiService.fetchUsers()
userDao.insertAll(users)
}
}
// Hilt sees UserRepository needs UserDao and ApiService,
// and automatically creates and injects them.@HiltViewModel
Пометьте ViewModel аннотацией @HiltViewModel и используйте @Inject constructor. Во Fragment получите его с помощью by viewModels():
@HiltViewModel
class UserViewModel @Inject constructor(
private val repo: UserRepository
) : ViewModel() {
val users = repo.getUsersFlow().asLiveData()
}
// In Fragment:
@AndroidEntryPoint
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels() // Hilt provides it
}@Module и @Provides
Если Hilt не может использовать внедрение через конструктор (например, для интерфейсов или сторонних классов), предоставьте экземпляры через @Module:
@Module
@InstallIn(SingletonComponent::class) // lives for app lifetime
object NetworkModule {
@Provides
@Singleton
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun provideApiService(retrofit: Retrofit): ApiService {
return retrofit.create(ApiService::class.java)
}
}@Binds — связывание интерфейса
Используйте @Binds, чтобы указать Hilt, какую реализацию применять для интерфейса:
interface AnalyticsService {
fun logEvent(name: String)
}
class FirebaseAnalytics @Inject constructor() : AnalyticsService {
override fun logEvent(name: String) { /* Firebase impl */ }
}
@Module
@InstallIn(SingletonComponent::class)
abstract class AnalyticsModule {
@Binds
@Singleton
abstract fun bindAnalytics(impl: FirebaseAnalytics): AnalyticsService
}Области действия Hilt
Области действия определяют, как долго существует внедрённый экземпляр:
@Singleton— один экземпляр в течение всего времени работы приложения (ApplicationComponent)@ActivityRetainedScoped— сохраняется при изменениях конфигурации@ActivityScoped— один экземпляр для каждой Activity@FragmentScoped— один экземпляр для каждого Fragment@ViewModelScoped— один экземпляр для каждогоViewModel
Тестирование с Hilt
Заменяйте настоящие зависимости имитациями в тестах с помощью поддержки тестирования Hilt:
@HiltAndroidTest
class UserRepositoryTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@Inject
lateinit var repo: UserRepository
@Before
fun setUp() {
hiltRule.inject()
}
@Test
fun usersAreFetched() {
assertNotNull(repo)
}
}Быстрая проверка
Какая аннотация указывает Hilt сгенерировать иерархию компонентов DI для всего приложения?
Повторение: внедрение зависимостей с Hilt
Hilt почти полностью автоматизирует DI в Android:
@HiltAndroidAppдля класса Application@AndroidEntryPointдля Activity и Fragment@Inject constructorдля классов, поддерживающих внедрение@HiltViewModel+@Inject constructorдля ViewModels@Module+@Providesдля сторонних классов и интерфейсов@Singletonдля совместного использования одного экземпляра во всём приложении
Далее: push-уведомления с помощью Firebase Cloud Messaging.
Часто задаваемые вопросы
Урок «Внедрение зависимостей с Hilt» бесплатный?
Да — полный текст урока «Внедрение зависимостей с Hilt» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 6 уроков всего.
Чему я научусь в уроке «Внедрение зависимостей с Hilt»?
Упростите управление зависимостями с помощью Hilt. Используйте @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel, @Module, @Provides и области @Singleton. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Android Academy?
Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 6 из 6.
Сколько времени занимает урок «Внедрение зависимостей с Hilt»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Android Academy?
Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- ViewModel и LiveData
- База данных Room
- Корутины и приостанавливаемые функции
- Шаблон репозитория
- Компонент навигации
- Внедрение зависимостей с Hilt