Dagger Hilt 错误注入 ActivityContext
Dagger Hilt error injecting ActivityContext
我在 ViewModel 中注入 Dagger-Hilt
一个 class,它依赖于 @ActivityContext
,这个模块安装在 ActivityComponent
中,作用域为 activity 每当我尝试编译时它都会抛出一个错误。为了您的信息,我有其他模块 ActivityRetainedComponent 和 SingletonComponent 注入 @ApplicationContext.
现在我想弄清楚这个错误是什么意思。
error: [Dagger/MissingBinding] com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract static class SingletonC implements App_GeneratedInjector,
^
com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils is injected at
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel(�, permissionsUtils, �)
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel is injected at
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel_HiltModules.BindsModule.binds(vm)
@dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.rober.fileshortcut_whereismyfile.App_HiltComponents.SingletonC ? com.rober.fileshortcut_whereismyfile.App_HiltComponents.ActivityRetainedC ? com.rober.fileshortcut_whereismyfile.App_HiltComponents.ViewModelC]
这是代码(我不认为这里有什么问题)
@Module
@InstallIn(ActivityComponent::class)
object PermissionModule {
@ExperimentalCoroutinesApi
@Provides
@ActivityScoped
fun providePermissionsHelper(
@ActivityContext context: Context,
) = PermissionsUtils(context)
}
@HiltViewModel
@ExperimentalCoroutinesApi
class FileViewModel @Inject constructor(
private val class1: Class1,
private val class2: Class2,
private val class3: Class3,
private val permissionsUtils: PermissionsUtils //Here's the one I'm injecting
)
我的猜测:它告诉我不能在 ActivityComponent 中注入,因为在 ActivityRetainedComponent/SingletonComponent/ViewModelComponent 中注入了 FileViewModel,因为在该组件中安装了提供给 viewmodel 的其他依赖项?
问题:这里到底发生了什么?我缺少什么,是否有使用 ActivityComponent 的解决方案? class!
我真的需要 @ActivityContext
编辑: 当我更改为 @InstallIn(ActivityRetainedComponent::class)
并将上下文更改为 @ApplicationContext context: Context
时,这有效,请注意它适用于 SingletonComponent/ViewModelComponent/ActivityRetainedComponent,它说得通。但我仍然不知道如何让它工作 @ActivityComponent
编辑 2: 我得出的结论是不可能的,因为您在 ViewModel 中安装并且与 ViewModel 一起使用的 组件是 Singleton/ActivityRetained/ViewModel
,因此无法在 ViewModel 中注入 ActivityContext
,因为它需要组件 @ActivityComponent
,并且它比 ViewModelComponent 低 1 级。
so there's no way to inject ActivityContext in a ViewModel since it requires the component @ActivityComponent and this is 1 level below of ViewModelComponent.
你明白了。
从生命周期的角度考虑 Dagger/Hilt 组件(和范围)。在 Android 中,ViewModel
的生命周期比其包含的 Activity
或 Fragment
更长。这就是 class 的全部要点,只是不幸的名字。将它们视为 RetainedInstance
或 AnObjectThatSurvivesActivityConfigurationChanges
可能会有所帮助。是的,这些不像 ViewModel
.
那样吸引人
如果你将一个短期对象(Activity
)注入到一个长期对象(ViewModel
)中,后者将保留对前者的引用。这是内存泄漏 - Activity
及其包含的所有内容(例如视图、位图)即使不再使用,也会保留在内存中。其中几个,你就有 OutOfMemoryError
.
的风险
然而,反过来——即将一个长寿命对象注入一个短寿命对象——是安全的。这就是为什么你让它与 Singleton
/ActivityRetained
/ViewModel
组件一起工作。
Hilt 的组件层次结构使您更难造成内存泄漏。所有这些都发生在编译时,与基于运行时的解决方案相比,它可以为您提供更快的反馈。比你的用户通过崩溃发现的要好得多!
我在 ViewModel 中注入 Dagger-Hilt
一个 class,它依赖于 @ActivityContext
,这个模块安装在 ActivityComponent
中,作用域为 activity 每当我尝试编译时它都会抛出一个错误。为了您的信息,我有其他模块 ActivityRetainedComponent 和 SingletonComponent 注入 @ApplicationContext.
现在我想弄清楚这个错误是什么意思。
error: [Dagger/MissingBinding] com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract static class SingletonC implements App_GeneratedInjector,
^
com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils is injected at
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel(�, permissionsUtils, �)
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel is injected at
com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel_HiltModules.BindsModule.binds(vm)
@dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.rober.fileshortcut_whereismyfile.App_HiltComponents.SingletonC ? com.rober.fileshortcut_whereismyfile.App_HiltComponents.ActivityRetainedC ? com.rober.fileshortcut_whereismyfile.App_HiltComponents.ViewModelC]
这是代码(我不认为这里有什么问题)
@Module
@InstallIn(ActivityComponent::class)
object PermissionModule {
@ExperimentalCoroutinesApi
@Provides
@ActivityScoped
fun providePermissionsHelper(
@ActivityContext context: Context,
) = PermissionsUtils(context)
}
@HiltViewModel
@ExperimentalCoroutinesApi
class FileViewModel @Inject constructor(
private val class1: Class1,
private val class2: Class2,
private val class3: Class3,
private val permissionsUtils: PermissionsUtils //Here's the one I'm injecting
)
我的猜测:它告诉我不能在 ActivityComponent 中注入,因为在 ActivityRetainedComponent/SingletonComponent/ViewModelComponent 中注入了 FileViewModel,因为在该组件中安装了提供给 viewmodel 的其他依赖项?
问题:这里到底发生了什么?我缺少什么,是否有使用 ActivityComponent 的解决方案? class!
我真的需要@ActivityContext
编辑: 当我更改为 @InstallIn(ActivityRetainedComponent::class)
并将上下文更改为 @ApplicationContext context: Context
时,这有效,请注意它适用于 SingletonComponent/ViewModelComponent/ActivityRetainedComponent,它说得通。但我仍然不知道如何让它工作 @ActivityComponent
编辑 2: 我得出的结论是不可能的,因为您在 ViewModel 中安装并且与 ViewModel 一起使用的 组件是 Singleton/ActivityRetained/ViewModel
,因此无法在 ViewModel 中注入 ActivityContext
,因为它需要组件 @ActivityComponent
,并且它比 ViewModelComponent 低 1 级。
so there's no way to inject ActivityContext in a ViewModel since it requires the component @ActivityComponent and this is 1 level below of ViewModelComponent.
你明白了。
从生命周期的角度考虑 Dagger/Hilt 组件(和范围)。在 Android 中,ViewModel
的生命周期比其包含的 Activity
或 Fragment
更长。这就是 class 的全部要点,只是不幸的名字。将它们视为 RetainedInstance
或 AnObjectThatSurvivesActivityConfigurationChanges
可能会有所帮助。是的,这些不像 ViewModel
.
如果你将一个短期对象(Activity
)注入到一个长期对象(ViewModel
)中,后者将保留对前者的引用。这是内存泄漏 - Activity
及其包含的所有内容(例如视图、位图)即使不再使用,也会保留在内存中。其中几个,你就有 OutOfMemoryError
.
然而,反过来——即将一个长寿命对象注入一个短寿命对象——是安全的。这就是为什么你让它与 Singleton
/ActivityRetained
/ViewModel
组件一起工作。
Hilt 的组件层次结构使您更难造成内存泄漏。所有这些都发生在编译时,与基于运行时的解决方案相比,它可以为您提供更快的反馈。比你的用户通过崩溃发现的要好得多!