android - 使用 HILT 对 ViewModel 的应用程序依赖
问题描述
我想知道如何使用 Hilt 将应用程序依赖项传递给 ViewModel?我正在尝试使用 AndroidViewModel,但我做不到。有人能帮我吗?一些简短的样本对我来说意义重大。
这是我的视图模型:
class MainViewModel @ViewModelInject constructor(
private val application: Application,
private val repository: Repository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
这是我的刀柄模块
@Module
@InstallIn(ApplicationComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDatabase(
@ApplicationContext context: Context
) = Room.databaseBuilder(
context,
MyDatabase::class.java,
"my_database"
).build()
@Singleton
@Provides
fun provideDao(database: MyDatabase) = database.myDao()
@Singleton
@Provides
fun provideRepository(myDao: MyDao) = Repository(myDao)
@Singleton
@Provides
fun provideApplicationContext() = MyApplication()
}
其他一切都很好,我收到了错误消息:
引起:java.lang.RuntimeException:无法创建类 com.example.example.viewmodel.MainViewModel 的实例 引起:java.lang.InstantiationException:java.lang.Class<com.example.example.viewmodel.MainViewModel> 有没有零参数构造函数
解决方案
您可以查看完整源代码https://github.com/Kotlin-Android-Open-Source/MVI-Coroutines-Flow/tree/dagger_hilt
- 存储库:
@Singleton
class UserRepositoryImpl @Inject constructor(
private val userApiService: UserApiService,
private val dispatchers: CoroutineDispatchers,
...
) : UserRepository { ... }
- 用例:
class AddUserUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke(user: User) = userRepository.add(user)
}
class RemoveUserUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke(user: User) = userRepository.remove(user)
}
class RefreshGetUsersUseCase @Inject constructor(private val userRepository: UserRepository) {
suspend operator fun invoke() = userRepository.refresh()
}
...
- 视图模型:
class MainVM @ViewModelInject constructor(
private val getUsersUseCase: GetUsersUseCase,
private val refreshGetUsers: RefreshGetUsersUseCase,
private val removeUser: RemoveUserUseCase,
) : ViewModel() { ... }
- 活动:
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), View {
private val mainVM by viewModels<MainVM>()
...
}
编辑:
注入应用程序上下文:
首先,去掉这个定义,因为Hilt
已经提供了应用上下文:
@Singleton
@Provides
fun provideApplicationContext() = MyApplication()
其次,在上下文参数上使用 @ApplicationContext 注释。
class MainViewModel @ViewModelInject constructor(
@ApplicationContext private val context: Context,
private val repository: Repository,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
推荐阅读
- angular - 预先设置今天日期以在 Angular 中输入类型日期
- android-studio - 如何在 Android Studio 中的右括号和左大括号之间自动添加空格?
- rest - 如何使用数据工厂 v2 将数据从 REST API 端点复制到 Azure DB?
- square-connect - Square POS API 的 iOS auto_return 超时是多少?
- python - MAPI 未定义
- c# - 用 C# dll 替换 ac api dll 而不影响客户端
- amazon-web-services - 想要 SNS 反复提醒
- php - 如何修复 Stripe 错误:网络错误 [errno 77]:错误设置证书验证位置
- wix - WIX 更新程序不使用以前版本的设置参数
- python-3.x - 无法在 docker-compose 文件中为 argparse 传递参数