Java – Restoring state when returning nested viewpager causes a crash

Restoring state when returning nested viewpager causes a crash… here is a solution to the problem.

Restoring state when returning nested viewpager causes a crash

I have a button to add ParentFragment. There is a Viewpager with two ListFragments. The first time I added ParentFragment, everything worked fine unless I pressed back and added ParentFragment again. ParentFragment is created as usual, but when it tries to create Viewpager, it somehow crashes the application.

                                      ParentFragment
                                           |
                                           V
                    ListFragment 1 <-- Viewpager --> ListFragment 2

Error log:

FATAL EXCEPTION: main
Process: at.umoser.fab.musikbox, PID: 16900
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:667)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1319)
at android.view.View.dispatchRestoreInstanceState(View.java:13639)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2889)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2895)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2895)
at android.view.View.restoreHierarchyState(View.java:13617)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:468)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1094)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

This is how I called Viewpager with getChildFragmentManager() in “ParentFragment**”:

mPager = (ViewPager) rootView.findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager(), connection);
mPager.setAdapter(mPagerAdapter);

Obviously using getChildFragmentManager() instead of getFragmentManager() is the right way to nest fragments, and while the application doesn’t crash when using getFragmentManager(), viewpager doesn’t appear at all.

Does the Viewpager or its Adapter call the onRestoreInstanceState/restoreState method on each creation (check the error log), or does the addition occur only the second time the ParentFragment is created?

If so, how do I force it to create everything from scratch instead of restoring the state? Or is there another solution.

Solution

I avoided state recovery by using the FragmentPagerAdapter instead of the FragmentStatePagerAdapter for my Viewpager adapter. I used the Android docs to create adapters but missed multiple pager adapters… It’s stupid.

Related Problems and Solutions