I got into to an issue with accessing viewmodel.
I have an activity and 2 fragments in it. I have a view model for the activity and fragment in using the same instance of the view model created in host activity.
class MyViewModel(var paymentDataModel: PaymentDataModel) : ViewModel(){
fun someMethod():Boolean{
//return Something
}
}
class MyViewModelFactory(var paymentDataModel: PaymentDataModel) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MyViewModel(paymentDataModel) as T
}
}
class NewPaymentAmountFragment : Fragment() {
private val paymentViewModel: MyViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if(paymentViewModel.someMehtod()){
//Accessing activity viewmodel in fragment
}
}
}
If I define viewmodel using viewModel extension in activity function it says the below error.
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.app.MyViewModel
class MyActivity : BaseActivity(){
val myViewModel: MyViewModel by viewModels {
MyViewModelFactory(constructPaymentDataModel()) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
But if I define ViewModel in a normal way using ViewModelProvider() its working.
class MyActivity : BaseActivity(){
lateint var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModelFactory = MyViewModelFactory(constructPaymentDataModel())
myViewModel = ViewModelProvider(this, viewModelFactory)[MyViewModel::class.java]
}
}
Also this happens only when viewmodel in fragment is accessed first.
If I accessed viewmodel in activity once before oncreate of activity , in fragment its working fine. Its able to get the viewmodel instance.
class MyActivity : BaseActivity(){
val myViewModel: MyViewModel by viewModels {
MyViewModelFactory(constructPaymentDataModel()) }
override fun onCreate(savedInstanceState: Bundle?) {
println(myViewModel.isPaymentMethodExists.value)
super.onCreate(savedInstanceState)
}
}
Here I accessed viewmodel before fragment accessing activities viewmodel. So here viewmodel is assigned by lazy when breakpoint comes to this println method.
The same , if I access viewmodel in fragment first . The lazy viewmodel in activity does not get assigned.
So here is the summary, if viewmodel is defined in both activity and fragment using viewmodel extensions and viewmodel is accessed in fragment first, its not working.