Search code examples
javaandroidandroid-fragmentsmvvmviewmodel

Get ViewModel in Fragment in onViewCreated vs in onCreate


I have an Android Activity which has a Fragment, let's name it MyFragment.

In MyFragment's onCreate() I get my ViewModel like this:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myViewModel = new ViewModelProvider(requireActivity()).get(MyViewModel.class);
}

Issue:

Sometimes, when I put the application on the background and I navigate to other apps, when I try to open and bring back to the foreground this app, the app crashes with this error:

Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.MyViewModel
    ...
    at com.example.MyFragment.onCreate(MyFragment.java:64)

where line 64 is this one:

myViewModel = new ViewModelProvider(requireActivity()).get(MyViewModel.class);

After looking into the ViewModel's official documentation, I noticed in the code snippets that in all the Fragments the ViewModel is gotten in onViewCreated() instead of onCreate(). I applied that change to my code and my application doesn't crash anymore with the aforementioned stacktrace.

Questions:

  1. Is there any particular reason why getting the ViewModel in a Fragment's onCreate() could result in an application crash and if so, then why getting the ViewModel on onViewCreated() appears to resolve this issue?

  2. Should we always get a ViewModel in a Fragment in onViewCreated() instead of on onCreate() as shown in the official documentation's code snippets?


Solution

  • This is due to the Fragment Life-Cycle that exist on android . You can have a more read about it here https://developer.android.com/guide/fragments/lifecycle.

    So basically , onCreate is only called when the fragment is created for the first time . And when you go into background and resume the app again , onCreate() function is not called and onCreateView() or onViewCreated is called() . Refer the image below . So , when you initialize viewModel in the OnCreate() and put the application in background and return to the application since no OnCreate() is called , viewModel is not created and thus it crashes . And when in OnViewCreated(), the viewModel is initialized when the application returns from the background and hence there is no crash . So , yes one should initialize it in the onViewCreate().

    enter image description here