The situation is : I tried to put a viewpager with a fragmentAdapter inside of another fragment, which is inside of a activity. And I tested these code on my Nexus5(5.1.1), they worked like a charm .And so did on our QA's phones.
But this morning , when I was 'enjoying' my regular online-app-running-data reading work, I found this crash happened over 150 times and continuely growing. I tried every method I could get, including the nest-fragments crashes we usually easy to get, and after a few searching on Internet, I concluded this result: "It's Google's mistake."
[Reason]
In Google's Android Source Code, something wierd found like this:
It means before 5.0.1, everytime a fragement invokes its onDestory or onDetach Method, its mChildFramentManager has never been reset. WOW. And I guess that's the reason.
If you look at the implementation of Fragment, you'll see that when moving to the detached state, it'll reset its internal state. However, it doesn't reset mChildFragmentManager (this is a bug in the current version of the support library). This causes it to not reattach the child fragment manager when the Fragment is reattached, causing the exception you saw.
/** * Adds an action to the queue of pending actions. * * @param action the action to add * @param allowStateLoss whether to allow loss of state information * @throws IllegalStateException if the activity has been destroyed */publicvoidenqueueAction(Runnableaction,booleanallowStateLoss){if(!allowStateLoss){checkStateLoss();}synchronized(this){if(mDestroyed||mActivity==null){thrownewIllegalStateException("Activity has been destroyed");}if(mPendingActions==null){mPendingActions=newArrayList<Runnable>();}mPendingActions.add(action);if(mPendingActions.size()==1){mActivity.mHandler.removeCallbacks(mExecCommit);mActivity.mHandler.post(mExecCommit);}}}
[Fix]
the answer is simple, we need to reset its child fragmentManager manully on devices carrying systems below Android 5.0.1.Here is the code , inside the onDetach method: