First, my app is a multi-module app.
My MainActivity creates an instance of RecordsViewModel in the next way:
private lateinit var recordsViewModel: RecordsViewModel
...
recordsViewModel = ViewModelProvider(this)[RecordsViewModel::class.java]
My RecordsViewModel definition:
@HiltViewModel
class RecordsViewModel
@Inject constructor(
private val userService: IUserService,
private val testService: ITestService,
private val testTypeService: ITestTypeService,
private val tmTest: TMTest) : ViewModel() {
private val recordsResult: MutableLiveData<String> = MutableLiveData()
All interfaces required by RecordsViewModel are defined in "Core" module (main have access to Core) and provided in a class / module called Dependencies (located in "Services" module, to which "Core" has access):
@Module
@InstallIn(SingletonComponent::class)
abstract class Dependencies {
@Binds
@Singleton
abstract fun bindsTestService(
testService: TestService
): ITestService
@Binds
@Singleton
abstract fun bindsUserService(
userService: UserService
): IUserService
@Binds
@Singleton
abstract fun bindsTestTypeService(
testTypeService: TestTypeService
): ITestTypeService
}
But at the moment of instantiating the RecordsViewModel, the next exception is thrown:
Cannot create an instance of RecordsViewModel Caused by: java.lang.InstantiationException: java.lang.Class<com.xxx.xxx.ui.activities.test.records.RecordsViewModel> has no zero argument constructor
Of course it has no zero argument constructor!!! it has dependencies! and Hilt is supposed to handle that, that's why we have the @HiltViewModel decorator.
OK, not sure it has something to do, but if you look, I'm not providing TMTest -which is a RecordsViewModel dependency- in any module, first, because I'm not sure I have to, second, because TMTest has many other dependencies that make me don't know how to deal with TMTest providing (still not sure is the error comes from TMTest not being provided or not).
I've tried:
@Provides
@Singleton
fun provideTMTest(tmTest: TMTest): TMTest {
return tmTest
}
but this leads me to "Cycle" dependencies that I don't know how to handle.
Other option could be:
@Provides
@Singleton
fun provideTMTest(): TMTest {
return TMTest(TMSecurity(AppRunService),TMSettings(),...)
}
But this is neverending, because every TMTest dependency has some other dependencies, and I don't even know if this is the correct way to provide a dependency that has other dependencies which at the same time has more dependencies...
I'm stuck without being able to create RecordsViewModel.
Ok, I've found the solution myself, and it was a very silly issue.
I forgot the @AndroidEntryPoint decorator over the Fragment:
@AndroidEntryPoint
class ResumeSectionFragment : Fragment() {
private lateinit var binding: ActivityMainBinding
private lateinit var recordsViewModel: RecordsViewModel
@Suppress("UNCHECKED_CAST")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
recordsViewModel = ViewModelProvider(this)[RecordsViewModel::class.java]