您好,我正在使用dagger 2进行依赖项注入,当我尝试在片段中注入MainActivityViewModel时,我得到了错误lateinit property viewModelx has not been initialized
这些是相关的依赖文件和片段
RetroModule
@Module
class RetroModule {
@Singleton
@Provides
fun getRetrofitInstance(): Retrofit {
return Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Singleton
@Provides
fun getApiService(): ApiServiceInterface =
getRetrofitInstance().create(ApiServiceInterface::class.java)
companion object {
private val baseURL = "https://android-interview.s3.eu-west-2.amazonaws.com/"
}
}
RetroComponent
@Singleton
@Component(modules = [RetroModule::class])
interface RetroComponent {
fun inject(mainActivityViewModel: MainActivityViewModel)
}
片段
class CreditScoreFragment : Fragment() {
@Inject lateinit var viewModelx: MainActivityViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCreditScoreBinding.inflate(inflater, container, false)
val view = binding.root
initViewModel()
initView()
return view
}
private fun initViewModel() {
viewModelx.getCreditReportObserver().observe(viewLifecycleOwner, Observer<CreditReport> {
showScoreUI(true)
binding.score.text = it.creditReportInfo.score.toString()
binding.maxScoreValue.text = "out of ${it.creditReportInfo.maxScoreValue}"
initDonutView(
it.creditReportInfo.score.toFloat(),
it.creditReportInfo.maxScoreValue.toFloat()
)
})
viewModelx.getServerErrorLiveDataObserver().observe(viewLifecycleOwner, Observer<Boolean> {
if(it) {
showScoreUI(false)
showToastMessage()
}
})
viewModelx.getCreditReport()
}
companion object {
@JvmStatic
fun newInstance() =
CreditScoreFragment().apply {}
}
}
错误更新
xxx/app/build/tmp/kapt3/stubs/debug/com/example/clearscore/di/ViewModelModule.java:18: error: @Binds methods' parameter type must be assignable to the return type
public abstract androidx.lifecycle.ViewModelProvider.Factory bindMainActivityViewModel_Factory(@org.jetbrains.annotations.NotNull()
^xxx/app/build/tmp/kapt3/stubs/debug/com/example/clearscore/di/RetroComponent.java:18: error: @Component.Factory abstract methods must return the @Component type or a supertype of the @Component. Inherited method: create(T)
public static abstract class Factory implements dagger.android.AndroidInjector.Factory<com.example.clearscore.MyApplication> {
^xxxapp/build/tmp/kapt3/stubs/debug/com/example/clearscore/di/RetroComponent.java:6: error: com.example.clearscore.di.ViewModelModule has errors
@dagger.Component(modules = {com.example.clearscore.di.RetroModule.class, com.example.clearscore.di.ViewModelModule.class})
ViewModelModule
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MainActivityViewModel::class )
// Bind your View Model here
abstract fun bindMainActivityViewModel(viewModel: MainActivityViewModel): ViewModel
@Binds
// Bind viewModelFactory if you have custom ViewModelFactory
abstract fun bindMainActivityViewModel_Factory(factory: MainActivityViewModel_Factory): ViewModelProvider.Factory
}
MainActivityViewModel_Factory
@DaggerGenerated
@SuppressWarnings({
"unchecked",
"rawtypes"
})
public final class MainActivityViewModel_Factory implements Factory<MainActivityViewModel> {
private final Provider<DataRepository> dataRepositoryProvider;
public MainActivityViewModel_Factory(Provider<DataRepository> dataRepositoryProvider) {
this.dataRepositoryProvider = dataRepositoryProvider;
}
@Override
public MainActivityViewModel get() {
return newInstance(dataRepositoryProvider.get());
}
public static MainActivityViewModel_Factory create(
Provider<DataRepository> dataRepositoryProvider) {
return new MainActivityViewModel_Factory(dataRepositoryProvider);
}
public static MainActivityViewModel newInstance(DataRepository dataRepository) {
return new MainActivityViewModel(dataRepository);
}
}
发布于 2021-08-20 20:05:43
您需要在视图模型模块中声明提供程序:
@Binds
@IntoMap
@ViewModelKey(MainActivityViewModel::class)
abstract fun provideMainActivityViewModel(viewModel: MainActivityViewModel): ViewModel
你的片段也必须在你的模块中声明:
@FragmentScope
@ContributesAndroidInjector
abstract fun provideCreditScoreFragment(): CreditScoreFragment
在您的代码片段中,当您声明viewmodel时,需要初始化它,例如使用延迟初始化,正如您所希望的那样:
private val viewModel: MainActivityViewModel by lazy {
ViewModelProvider(this, yourViewModelFactory).get(MainActivityViewModel::class.java)
}
最后,您可以在片段中注入视图模型工厂(请记住在模块中声明工厂)
https://stackoverflow.com/questions/68867346
复制相似问题