我从我的应用程序中获取用户报告,提供以下异常:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1109)
at android.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:399)
at android.app.Activity.onBackPressed(Activity.java:2066)
at android.app.Activity.onKeyUp(Activity.java:2044)
at android.view.KeyEvent.dispatch(KeyEvent.java:2529)
at android.app.Activity.dispatchKeyEvent(Activity.java:2274)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.widget.TabHost.dispatchKeyEvent(TabHost.java:297)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1112)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1855)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1277)
at android.app.Activity.dispatchKeyEvent(Activity.java:2269)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1803)
at android.view.ViewRoot.deliverKeyEventPostIme(ViewRoot.java:2880)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2853)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2028)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4028)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) …Run Code Online (Sandbox Code Playgroud) android illegalstateexception android-fragments android-viewpager fragmenttransaction
我将我的Android应用程序移植到了蜂窝状态,然后为了使用碎片我做了一个大的重构.在我之前的版本中,当我按下Home按钮时,我曾经做过一次ACTIVITY_CLEAR_TOP以重置后台堆栈.
现在我的应用程序只是一个包含多个片段的Activity,因此当我按下Home按钮时,我只需替换其中的一个片段.如何清除,而不必使用我的背部栈startActivity与ACTIVITY_CLEAR_TOP标志?
我有一个活动A,它调用片段Bf,它调用片段Cf. 我希望在调用Cf时将Bf放在backstack中,以便用户可以导航回它.但是,如果在Cf中按下特定按钮,我希望将Bf从后台堆叠中移除.这可能吗?
我看到有一个popBackStack()函数.但是,我对这将如何工作有点困惑.使用此功能是否安全?在Backstack上Bf之后是否有可能插入来自不同应用程序的活动?
另外,有没有办法改变backstack上片段的savedInstanceState?
我只是无法弄清楚如何使用模拟器在backstack上进行强大的测试.

假设我有一个包含两个FrameLayouts的Activity(让我们称之为FrameA和FrameB),它们每个都包含一个Fragment(让我们分别称它们为FragmentA1和FragmentB1).现在,我使用类似于以下代码提交一系列单独的片段事务...
getFragmentManager()
.beginTransaction()
.replace(frameId, fragment)
.addToBackStack(null)
.commit();
Run Code Online (Sandbox Code Playgroud)
...这样我用FramementA2替换FrameA中的FragmentA1,然后用FragmentB2替换FrameB中的FragmentB1,然后用FragmentA3替换FrameA中的FragmentA2,然后用FragmentB3替换Frame2中的FragmentB2,最终状态如上图所示(其中只有FragmentA3和FragmentB3可见).
如果我正确理解后栈是如何工作的,按"后退"将交错在FrameA和FrameB之间弹出片段(反映我是如何添加它们的).
有谁知道是否有可能选择性地在FrameA或FrameB上弹出最后一笔交易?(即如果我按下'Pop FrameA',那么FrameA将从FragmentA3转换回FragmentA2,相反,如果我按下'Pop FrameB',那么FrameB将从FragmentB3转换回FragmentB2)
补充:我知道我可以使用该
FragmentManager.findFragmentById(int framelayoutId)方法将片段最后添加到给定的FrameLayout ,但调用FragmentTransaction.remove(fragment).commit()仅从视图中删除片段,并且不会将视图转换回先前显示的片段.
我的项目包含两个片段:
fragmentA单击按钮完成时的操作.这是我主视图的XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/main_fragment_container"
android:name="fragmentA"
android:layout_width="match_parent"
android:layout_height="match_parent">
</fragment>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
当我想以取代FragmentA由FragmentB,我用这个代码:
FragmentTransaction fragmentTransaction = getSupportFragmentManager()
.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB());
fragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常.我的FragmentA被新的替换FragmentB.但是,当点击上后退按钮做的,我希望更换FragmentB被FragmentA使用popBackStackImmediate().
这是我使用的代码:
if (getSupportFragmentManager().getBackStackEntryCount() > 0){
boolean done = getFragmentManager().popBackStackImmediate();
fragmentTransaction.commit();
}
Run Code Online (Sandbox Code Playgroud)
该函数popBackStackImmediate返回false并且FragmentB仍处于前台.
我打电话时为什么FragmentA不会替换FragmentB popBackStackImmediate?有人有想法解决我的问题吗?
提前致谢
ANR是异常,错误还是什么?我们真的可以在一个try{} catch(){}结构中捕获它吗?
我有像这样的Fragment堆栈
F1 -> F2 -> F3 -> F4 -> F5
Run Code Online (Sandbox Code Playgroud)
现在我需要删除F2,F3,F4片段.
我需要如果我按下F5片段的后退按钮,它应该转到F1.
注意:我没有从活动中更改片段片段.从片段改变片段.
我有一种情况,我想从堆栈中清除所有片段,除了可见的片段(即顶部)
例如,后堆栈A-> B-> C-> D中有四个片段(D在顶部)
现在,我想从堆栈中删除片段A,B,C。但约束条件是从后堆栈中删除历史记录时,片段D上不应有任何可见的影响。
这是我的代码。
FragmentManager fm = getActivity().getSupportFragmentManager();
Bundle bundle = new Bundle();
OrderReceiptFragment orderReceiptFragment = new OrderReceiptFragment();
bundle.putSerializable("orderHistory", orderHistory);
orderReceiptFragment.setArguments(bundle);
CommonUtil.clearBackstack(fm);
fm.beginTransaction().setCustomAnimations(R.anim.enter_from_left,
R.anim.exit_to_right)
.replace(R.id.container, orderReceiptFragment).commit();
Run Code Online (Sandbox Code Playgroud)
清除堆栈的方法
public static void clearBackstack(FragmentManager fragmentManager) {
fragmentManager.popBackStack(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是-在清理后退堆栈的同时,在几毫秒的时间内,后退堆栈的第一个片段都可见。看起来很奇怪。有人对此有解决方案吗?