Android FragmentManager里activity has destroyed 崩溃
在开发中会遇到这样的需求,一个TabLayout+ViewPager+Fragment,在Fragment里依旧可以再次切换Fragment(当然这是我的实现方式),在部分机型上会出现崩溃,主要集中在三星、LG、Zmax上
google统计崩溃如下
ava.lang.IllegalStateException:
at android.support.v4.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1864)
at android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java:649)
at android.support.v4.app.BackStackRecord.commitAllowingStateLoss (BackStackRecord.java:614)
at xxx.xxx.xxx.fragment.storehome.XXXXFragment.updateContent (XXXXFragment.java:529)
at xxx.xxx.xxx.xxx.storehome.XXXXXFragment.bindData2UI (XXXXXFragment.java:683)
at xxx.xxx.xxx.xxx.storehome.XXXXXFragment.access$300 (XXXXXXFragment.java:66)
at xxx.xxx.xxx.xxx.storehome.XXXXXFragment$2.onSuccess (xxxxxxFragment.java:636)
at com.loopj.android.http.AsyncHttpResponseHandler.handleMessage (AsyncHttpResponseHandler.java:365)
at com.loopj.android.http.AsyncHttpResponseHandler$ResponderHandler.handleMessage (AsyncHttpResponseHandler.java:135)
at android.os.Handler.dispatchMessage (Handler.java:102)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:6776)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1410)
之前在网上查看有人说是使用commitWithLossState的提交方法,验证依然不行,并且公司测试机无法复现bug,只能在不断地寻找实验。
最后在网上查看了一些资料总与解决方法如下
在父fragment中,onCreate()使用getChildFragmentManager();获取FragmentManager,
mFragmentManager = getChildFragmentManager();
然后再onCreateView中加入如下代码
try { Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, mFragmentManager); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); }
最后在onDestoryView中添加如下代码
try { Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager"); childFragmentManager.setAccessible(true); childFragmentManager.set(this, null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); }