Hi I am using dagger 2 for dependency injection and when I try to inject MainActivityViewModel in my fragment I get the error lateinit property viewModelx has not been initialized
these are the related dependency files and Fragment
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)
}
Fragment
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 {}
}
}
Error update
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);
}
}
You need to declare the provider in your viewmodel module:
@Binds
@IntoMap
@ViewModelKey(MainActivityViewModel::class)
abstract fun provideMainActivityViewModel(viewModel: MainActivityViewModel): ViewModel
I think you are missing onething. Add AndroidSupportInjection.inject(this) in onAttach or onCreate based on when u start using your dependency this will help dagger to inject.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.