Вот шаги, которые я проделал, и мои ключевые выводы для преобразования моего новостного приложения для Android на использование инъекции зависимостей hilt
Эта статья была первоначально опубликована на vtsen.hashnode.dev 16 июля 2022 года.
Итак, я выполнил шаги из статьи «Как реализовать Hilt в приложении Android?», чтобы преобразовать приложение Android News для использования инъекции зависимостей Hilt. Отличие предыдущей статьи в том, что в ней не рассматривается инъекция зависимостей View Model.
1. Добавьте зависимости и @HiltAndroidApp
.
Начальные шаги по настройке точно такие же, как описано ниже:
- Установка зависимостей Hilt
- Добавьте @HiltAndroidApp в класс вашего приложения.
2. Добавьте @HiltViewModel
и @Inject Constructor
.
Чтобы Hilt создал MainViewModel
, вам необходимо аннотировать класс с помощью @HiltViewModel
. @Inject constructor
также используется, чтобы сообщить Hilt, как могут быть созданы зависимости.
@HiltViewModel
class MainViewModel
@Inject constructor(
private val repository: ArticlesRepository,
) : ViewModel() {
...
}
Я также использую @Inject Constructor
на SqlArticlesRepository
.
class SqlArticlesRepository @Inject constructor(
private val database: ArticlesDatabase,
private val webService: WebService,
) : ArticlesRepository {
...
}
3. Добавьте @Provides
и @Binds
.
Для создания зависимостей мы используем либо @Provides, либо @Binds. @Provides
используется для создания экземпляров ArticlesDatabase
и WebService
.
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
@Provides
@Singleton
fun provideDatabase(@ApplicationContext appContext: Context): ArticlesDatabase {
return Room.databaseBuilder(
appContext,
ArticlesDatabase::class.java,
"articles.db",
)
.fallbackToDestructiveMigration()
.build()
}
}
@Module
@InstallIn(SingletonComponent::class)
object WebServiceModule {
@Provides
@Singleton
fun provideWebService(): WebService {
return WebService()
}
}
@Binds
используется для создания реализации интерфейса ArticlesRepository
.
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindArticlesRepository(impl: SqlArticlesRepository): ArticlesRepository
}
4. Вызовите hiltViewModel()
Composable
Теперь все готово! Все ручные создания ниже в MainActivity
могут быть удалены.
private val repository by lazy {
SqlArticlesRepository(
ArticlesDatabase.getInstance(application),
WebService(),
)
}
private val homeViewModel by viewModels<MainViewModel> {
MainViewModelFactory(repository)
}
Создание MainViewModel
можно выполнить, вызвав композитную функцию hiltViewModel()
, которая генерирует все необходимые зависимости.
Например, замените эту функцию MainScreen
композитной функцией
MainScreen(homeViewModel, useSystemUIController = true)
на
MainScreen(viewModel = hiltViewModel(), useSystemUIController = true)
Создание базы данных ниже также может быть удалено, поскольку оно было предоставлено hilt @Provides
выше.
companion object {
@Volatile
private lateinit var instance: ArticlesDatabase
fun getInstance(context: Context): ArticlesDatabase {
synchronized(this) {
if (!::instance.isInitialized) {
instance = Room.databaseBuilder(
context.applicationContext,
ArticlesDatabase::class.java,
"articles.db")
.fallbackToDestructiveMigration()
.build()
}
return instance
}
}
}
Этот MainViewModelFactory
также может быть удален, поскольку об этом позаботился @HiltViewModel
.
@Suppress("UNCHECKED_CAST")
class MainViewModelFactory(private val repository: ArticlesRepository)
: ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
return MainViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Заключение
Все мои установленные модули Hilt находятся в области SingletonComponent
. Если я меняю установленный модуль на другой компонент, например, ViewModelComponent
или ActivityComponent
, он не компилируется, и я не знаю, как это исправить. Думаю, это мой следующий шаг в работе с этим Hilt
.
Да, мне все еще не нравится Hilt
. Называйте меня великим папой, но я все еще предпочитаю ручной ввод зависимостей, как этот:
- Рекомендуемые способы создания ViewModel или AndroidViewModel
Исходный код
- Репозиторий GitHub: Android News (ветка Hilt)
- Разница между ветками: Master vs Hilt
Смотрите также
- Советы и рекомендации по разработке Android