当前位置:网站首页>将视图模型转换为使用 Hilt 依赖注入

将视图模型转换为使用 Hilt 依赖注入

2022-08-10 20:29:00 程序员小何SS

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()可组合

现在完成了!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)

下面的数据库创建也可以删除,因为它是由@Provides上面的 hilt 提供的。

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范围内。如果我将已安装的模块更改为另一个组件,例如ViewModelComponentor ActivityComponent,它将无法编译,并且我不知道如何修复它,我想这是我下一步要解决这个问题Hilt。

原网站

版权声明
本文为[程序员小何SS]所创,转载请带上原文链接,感谢
https://blog.csdn.net/xiaokangss/article/details/126263374