I need some help to ressolve the following crash. I am refreshing my list on Restart in Activity
by calling fragment
in viewpager
to refresh its list. Following is the stacktrace of the crash:
Caused by java.lang.IllegalStateException: Can't create ViewModelProvider for detached fragment
at android.arch.lifecycle.ViewModelProviders.checkActivity(ViewModelProviders.java:51)
at android.arch.lifecycle.ViewModelProviders.of(ViewModelProviders.java:105)
at com.ui.fragments.mainpagerfragments.ConversationListFragment.searchConversation(ConversationListFragment.java:383)
at com.ui.activities.HomeActivity.onRestart(HomeActivity.java:288)
at android.app.Instrumentation.callActivityOnRestart(Instrumentation.java:1256)
at android.app.Activity.performRestart(Activity.java:6365)
at android.app.Activity.performResume(Activity.java:6376)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3299)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3345)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1532)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5728)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
call from activity onRestart :
((MyListFragment) adapter.getFragmentAtPosition(0)).search("");
method in fragment :
public void search(String query) {
query = "%" + query + "%";
if (myListViewModel == null) {
myListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MyListViewModel.class);
}
if (myListViewModel.mList != null && myListViewModel.mList.hasActiveObservers()) {
myListViewModel.mList.removeObservers(this);
}
myListViewModel.getFilteredList(query).observe(this, mainObserver);
}
If you're using a viewpager, be sure that the corresponding fragment is actually attached to its activity (this is what the error tries to tell you). It might happen that the fragment is not visible, thus it's not attached (depending on how the view pager was configured).
a quick&dirty fix:
public void search(String query) {
if(!isAdded()) return; //<---- returns if the fragment is not attached
query = "%" + query + "%";
if (myListViewModel == null) {
myListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MyListViewModel.class);
}
if (myListViewModel.mList != null && myListViewModel.mList.hasActiveObservers()) {
myListViewModel.mList.removeObservers(this);
}
myListViewModel.getFilteredList(query).observe(this, mainObserver);
}
However, you should re-investigate in your architecture, because those checks often imply some other code smells. When you're working with the new Android Architecture Patterns, there should be no need of this check as the lifecycle pattern handles all this for you: https://developer.android.com/topic/libraries/architecture/lifecycle
So, basically, you should not directly call any function of a fragment directly, instead call the corresponding business logic, which notifies the fragment to update its views.