异常:java.lang.IllegalStateException: Fragment no longer exists for key f0: unique id 0aa277f1-a562-499e-b765-08317f40c04c
Process: com.xxx.xxx, PID: 15243
java.lang.IllegalStateException: Fragment no longer exists for key f0: unique id 0aa277f1-a562-499e-b765-08317f40c04c
at androidx.fragment.app.FragmentManager.getFragment(FragmentManager.java:960)
at androidx.fragment.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:328)
at androidx.viewpager.widget.ViewPager.onRestoreInstanceState(ViewPager.java:1461)
at android.view.View.dispatchRestoreInstanceState(View.java:21866)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4047)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4053)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4053)
at android.view.View.restoreHierarchyState(View.java:21844)
at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:639)
at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:3010)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3001)
at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:580)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1971)
at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:249)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:26791)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:26791)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7066)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:26791)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7066)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:26791)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7066)
at com.android.internal.policy.DecorView.measureChildWithMargins(DecorView.java:3504)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:999)
at android.view.View.measure(View.java:26791)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4253)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2841)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3175)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2550)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9652)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1480)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1488)
at android.view.Choreographer.doCallbacks(Choreographer.java:1111)
at android.view.Choreographer.doFrame(Choreographer.java:1016)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1463)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:223)
at android.os.Looper.loop(Looper.java:324)
at android.app.ActivityThread.main(ActivityThread.java:8470)
at java.lang.reflect.Method.invoke(Native Method)
2023-08-03 14:37:48.788 15243-15243/? E/AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:582)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1059)
解决方法两种
① 设置Viewpager的isSaveEnabled
viewPager.setSaveEnabled(false);
② 重写FragmentStatePagerAdapter中的saveState方法
@Override
public Parcelable saveState() {
return null;
}
好久没用过Viewpager了,记录一下。
FragmentPagerAdapter、FragmentStatePagerAdapter比较
- FragmentPagerAdapter类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页面,数量也比较少的那种。Fragment在切换的时候,不会销毁,而只是调用事务中的detach方法,我们只会把我们的Fragment的view销毁,而保留了以前的Fragment对象。所以通过这种方式创建的Fragment一直不会被销毁。
- FragmentSatetePagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,仅保留状态信息,释放其资源;而在页面需要显示时,恢复状态信息,更节省内存。
Fragment 生命周期
-
Fragment 创建:setUserVisableHint() -> onAttach() ->onCreate() ->onCreateView() -> onActivityCreated() -> onStart() -> onResume()
-
Fragment变为不可见状态(锁屏、回到桌面、被Activity完全覆盖):onPause() -> onSaveInstanceState() -> onStop()
-
Fragment变为部分可见状态(打开Dialog样式的Activity):onPause() -> onSaveInstanceState()
-
Fragment由不可见变为活动状态:onStart() -> OnResume()
-
Fragment由部分可见变为活动状态:onResume()
-
退出应用:onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()(注意退出不会调用onSaveInstanceState方法,因为是人为退出,没有必要再保存数据)
-
Fragment被回收又重新创建:被回收执行onPause() -> onSaveInstanceState() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()
-
重新创建执行:onAttach() -> onCreate() -> onCreateView() -> onActivityCreated() -> onStart() -> onResume() -> setUserVisibleHint()
-
横竖屏切换:与Fragment被回收又重新创建一样。