首页 > 解决方案 > Dagger Hilt 不能用另一个字符串作为 ViewModel 中的依赖项注入字符串

问题描述

这些是我的刀柄依赖项-

//Dagger Hilt
implementation "com.google.dagger:hilt-android:2.33-beta"
kapt "com.google.dagger:hilt-compiler:2.33-beta"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
kapt "androidx.hilt:hilt-compiler:1.0.0-beta01"

这是我的两个模块

应用模块.kt

    @Module
    @InstallIn(SingletonComponent::class) //scope - entire application
    object AppModule {
    
        @Singleton // single instance in application
        @Provides // provide this dependency
        @Named(Consts.String1) // name in case of conflict
        fun provideTestString1() = "Injected String from String1"
    
    }

主模块.kt

@Module
@InstallIn(ActivityComponent::class) // scope - activities
object MainModule {

    @ActivityScoped // single instance in Activity
    @Provides // provide this dependency
    @Named(Consts.String2) //name in case of conflict
    fun provideTestString2(@ApplicationContext context:Context,@Named(Consts.String1) testStringFromApplication:String) = context.getString(R.string.string_to_inject) +" $testStringFromApplication"

}

这是我的视图模型

@HiltViewModel
class TestViewModel @Inject  constructor(@Named(Consts.String2) testStringFromViewModel: String) : ViewModel() {

    init {
        Log.d(Consts.TAG, "String from viewModel : $testStringFromViewModel")
    }
}

这是我只是试图记录注入的字符串的活动。

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private  val viewmodel : TestViewModel by viewModels() // injecting viewModel

    @Inject
    @Named(Consts.String1)
    lateinit var testString : String
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.d(Consts.TAG, testString)

       viewmodel
    }
}

常量.kt

object Consts {
    const val TAG = "mDependencyInjection"
    const val String1 = "String1"
    const val String2 = "String2"
}

错误

public abstract static class SingletonC implements MyApplication_GeneratedInjector,
                         ^
      @javax.inject.Named("String2") java.lang.String is injected at
          com.example.daggerhilt.TestViewModel(testStringFromViewModel)
      com.example.daggerhilt.TestViewModel is injected at
          com.example.daggerhilt.TestViewModel_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.example.daggerhilt.MyApplication_HiltComponents.SingletonC ? com.example.daggerhilt.MyApplication_HiltComponents.ActivityRetainedC ? com.example.daggerhilt.MyApplication_HiltComponents.ViewModelC]

当我在视图模型中注入字符串 1 时,它工作正常,但是当我尝试将字符串 2 注入视图模型时。弹出上面的错误。

链接到我正在关注的教程https://www.youtube.com/watch?v=ZE2Jkvnk2Bs&ab_channel=PhilippLackner

https://github.com/philipplackner/HiltTutorial

标签: androiddagger-hilt

解决方案


ViewModel 的寿命比 Activity 长,因此您不能将 Activity 范围内的依赖项提供给 ViewModel。您的 String1 依赖项的范围为 Singleton,因此可以在任何地方使用,但 String2 的范围为 Activity,因此不能在 ViewModel 中使用,这就是它在您的示例中不起作用的原因。

将 MainModule 调整为更高的范围,它将起作用。您可以在此处查看范围层次结构。因此,要注入 ViewModel,请使用ActivityComponent/以上的任何内容@ActivityScoped,例如

@Module
@InstallIn(ViewModelComponent::class)
object MainModule {

    @Provides
    @ViewModelScoped
    @Named(Consts.String2)
    fun provideTestString2(@ApplicationContext context:Context, @Named(Consts.String1) testStringFromApplication:String) = context.getString(R.string.string_to_inject) +" $testStringFromApplication"
}

推荐阅读