首页 > 代码库 > 调用getChildFragmentManager时出现的Bug

调用getChildFragmentManager时出现的Bug


异常:

java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1342)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)

at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)

at android.support.v4.view.ViewPager.populate(ViewPager.java:1012)

at android.support.v4.view.ViewPager.populate(ViewPager.java:881)

at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:434)

at com.itcode.reader.fragment.MineFragment.onViewCreated(MineFragment.java:49)

at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:925)

at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)

at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)

at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)

at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)

at android.os.Handler.handleCallback(Handler.java:615)

at android.os.Handler.dispatchMessage(Handler.java:92)

at android.os.Looper.loop(Looper.java:137)

 

场景:

Fragment中有一个ViewPager,ViewPager的每个pagerFragment

调用代码:

@Override

public void onViewCreated(View view, Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

viewPager = (ViewPager) view.findViewById(R.id.pager);

ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager(),TITLE);

viewPager.setAdapter(adapter);

TabPageIndicator mIndicator = (TabPageIndicator) view.findViewById(R.id.indicator);

mIndicator.setViewPager(viewPager);

}

解决方案:

在每个调用getChildFragmentManager()fragment中加入:

@Override

public void onDetach() {

super.onDetach();

try {

Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");

childFragmentManager.setAccessible(true);

childFragmentManager.set(thisnull);

catch (NoSuchFieldException e) {

throw new RuntimeException(e);

catch (IllegalAccessException e) {

throw new RuntimeException(e);

}

}

即可!


异常解析:

如果你仔细查看Fragment的实现,你会看到当fragment进行到detached状态时,它会重置它的内部状态。

然而,它没有重置mChildFragmentManager.这是当前版本support库的一个bug.

这导致在Fragment重新attach时,它(fragment)没有重新attachm childFragmentManager,从而引发了上面的异常.


调用getChildFragmentManager时出现的Bug