Bar*_*fet 9 android dependency-injection dagger-2 dagger-hilt
我正在注入Dagger-Hilt一个依赖于@ActivityContextViewModel 的类,该模块安装在ActivityComponent活动中并限定范围,每当我尝试编译时,它都会抛出错误。供您参考,我还有其他带有 ActivityRetainedComponent 和 SingletonComponent 注入 @ApplicationContext 的模块。
现在我试图弄清楚这个错误是什么意思。
\nerror: [Dagger/MissingBinding] com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils cannot be provided without an @Inject constructor or an @Provides-annotated method.\n public abstract static class SingletonC implements App_GeneratedInjector,\n ^\n com.rober.fileshortcut_whereismyfile.utils.PermissionsUtils is injected at\n com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel(\xef\xbf\xbd, permissionsUtils, \xef\xbf\xbd)\n com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel is injected at\n com.rober.fileshortcut_whereismyfile.ui.fragments.filefragment.FileViewModel_HiltModules.BindsModule.binds(vm)\n @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at\n 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]\nRun Code Online (Sandbox Code Playgroud)\n这是代码(我不认为这里有什么问题)
\n@Module\n@InstallIn(ActivityComponent::class)\nobject PermissionModule {\n\n @ExperimentalCoroutinesApi\n @Provides\n @ActivityScoped\n fun providePermissionsHelper(\n @ActivityContext context: Context,\n ) = PermissionsUtils(context)\n}\nRun Code Online (Sandbox Code Playgroud)\n@HiltViewModel\n@ExperimentalCoroutinesApi\nclass FileViewModel @Inject constructor(\n private val class1: Class1,\n private val class2: Class2,\n private val class3: Class3,\n private val permissionsUtils: PermissionsUtils //Here\'s the one I\'m injecting\n)\nRun Code Online (Sandbox Code Playgroud)\n我的猜测:它告诉我无法注入 ActivityComponent,因为 FileViewModel 被注入到 ActivityRetainedComponent/SingletonComponent/ViewModelComponent 中,因为提供给 viewmodel 的其他依赖项安装在该组件中?
\n问题:这里到底发生了什么?我缺少什么以及使用 ActivityComponent 有什么解决方案吗?我真的需要@ActivityContext那堂课!
编辑:当我更改为@InstallIn(ActivityRetainedComponent::class)并将上下文更改为@ApplicationContext context: Context时,这有效,请注意,它适用于 SingletonComponent/ViewModelComponent/ActivityRetainedComponent,这是有道理的。但我仍然不知道如何让它发挥作用@ActivityComponent
编辑2:我得出的结论是不可能的,因为您在 ViewModel 中安装并且与ViewModel 一起使用的组件是 Singleton/ActivityRetained/ViewModel,所以没有办法注入ActivityContextViewModel 因为它需要该组件@ActivityComponent,这是ViewModelComponent 下面 1 级。
来源: https: //dagger.dev/hilt/components#fn :1
\n小智 18
因此无法在 ViewModel 中注入 ActivityContext,因为它需要组件 @ActivityComponent,而该组件比 ViewModelComponent 低 1 级。
你说对了。
从生命周期的角度考虑 Dagger/Hilt 组件(和范围)。在 Android 中, aViewModel的生命周期比其包含的Activity或更长Fragment。这就是这门课的全部意义,只是名字很不幸。将它们视为RetainedInstance或可能会有所帮助AnObjectThatSurvivesActivityConfigurationChanges。是的,这些不像 那样吸引人ViewModel。
如果您将一个短期对象(the Activity)注入到一个长期对象(the ViewModel)中,后者将保留对前者的引用。这是内存泄漏 -Activity它及其包含的所有内容(例如视图、位图)仍然保留在内存中,即使不再使用。如果有其中几个,您就会面临OutOfMemoryError.
然而,相反的方式——即将长寿命的对象注入短寿命的对象中——是安全的。这就是为什么你让它与Singleton//组件ActivityRetained一起工作ViewModel。
Hilt 的组件层次结构使您更难造成内存泄漏。所有这些都发生在编译时,与基于运行时的解决方案相比,这可以为您提供更快的反馈。比你的用户通过崩溃发现要好得多!
| 归档时间: |
|
| 查看次数: |
4955 次 |
| 最近记录: |