Android: ViewModel. Failed to call observer method

murt picture murt · Jul 21, 2017 · Viewed 7.5k times · Source

I'm using new arch. components from google.

I have in Activity Login/Registering Fragments that are managed thanks to FragmentTransaction

Activity->RegisterFragment (with ViewPager) -> RegistrationSteps (adapter)

Inside RegisterFragment I have ViewPager. I want that all pages inside ViewPager will use the same ViewModel.

Those are registration steps (RegistrationStepFragment) that takes parent RegistrationFragment LifecycleOwner that scoped ViewModel to it- I just wanted ViewModel to be scoped to this parent Fragment.

RegistrationFragment.class inhered from

public interface FragmentViewPagerListener<T extends LifecycleFragment> {
    void nextPage();
    T getLifecycleFragment();
}

RegistartionSteps (pages) inhered from

public abstract class RegisterStepFragment extends LifecycleFragment {
    protected FragmentViewPagerListener mListener;
    protected RegisterViewModel mViewModel;

    public void setListener(FragmentViewPagerListener fragmentViewPagerListener) {
        this.mListener = fragmentViewPagerListener;
    }

    protected abstract void observeViewModel();

    @Override
    public void onCreated(@Nullable Bundle savedInstanceState) {
        super.onCreated(savedInstanceState);
        mViewModel = ViewModelProviders.of(mListener.getLifecycleFragment()).get(RegisterViewModel.class);
        observeViewModel();
    }

    protected abstract boolean validateData();
}

All goes well until I reach 3 page, and I want to move back (to second page) Then is thrown exception in mViewPager.setCurrentItem(1) (page 2: index: 1)

*java.lang.RuntimeException: Failed to call observer method
                                                                      at android.arch.lifecycle.ReflectiveGenericLifecycleObserver.invokeCallback(ReflectiveGenericLifecycleObserver.java:79)
                                                                      at android.arch.lifecycle.ReflectiveGenericLifecycleObserver.invokeMethodsForEvent(ReflectiveGenericLifecycleObserver.java:53)
                                                                      at android.arch.lifecycle.ReflectiveGenericLifecycleObserver.invokeCallbacks(ReflectiveGenericLifecycleObserver.java:61)
                                                                      at android.arch.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:45)
                                                                      at android.arch.lifecycle.LifecycleRegistry$ObserverWithState.sync(LifecycleRegistry.java:209)
                                                                      at android.arch.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:102)
                                                                      at android.arch.lifecycle.Li*fecycleDispatcher.dispatchIfLifecycleOwner(LifecycleDispatcher.java:150)

EDIT

Ok, I've found out that when moving to previous page, Fragment was reCreated calling and mViewModel.observable() received previously SUCCESS message and caused viewpager to move forward, that causes to destroy just created fragment what was causing error.

Solution is to create SingleEventLiveData that emits values only when post is called (don't notify observer if value changed before observer attached)

I mark it as CLOSE

Answer