fragment
栈操作时遇到一个问题
supportFragmentManager.beginTransaction()
.replace(R.id.xxx, xxxFragment)
.addToBackStack(null).commitNowAllowingStateLoss();
抛出异常:
Caused by: java.lang.IllegalStateException: This transaction is already being added to the back stack
at android.support.v4.app.BackStackRecord.disallowAddToBackStack(BackStackRecord.java:600)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:678)
看异常 哦 原来是 已经被 加入栈了,那就去掉 .addToBackStack(null) 这句话 显然 好使了 能正常显示fragment。但是还有一个 就是按返回键 或者 别的操作 要把上一个fragment从 BackStack 中拿出来 。
从fragment的回退栈中取东西 需要用 :supportFragmentManager.popBackStackImmediate();
可是怎么都没法回退, 还真是奇了怪了!
分析:
回退栈中是否有这个fragment
supportFragmentManager.getBackStackEntryCount()
这个方法可以查看fragment 回退栈的个数 发现 竟然是 0 看来并没有入站啊
先贴上解决方案
supportFragmentManager.beginTransaction()
.replace(R.id.fl_increment_need_info, getNeedInfoFragment(tag))
.addToBackStack(null).commit();
.addToBackStack(null).commit();
这样就没有问题了。
抱着求知的心态 让我们看看 为什么 commitNowAllowingStateLoss这个方法不能 入栈:
首先fragment事物的提交方式有四种:
/**
* 摘出其中的关键点
* it will be scheduled as work on the main thread
* to be done the next time that thread is ready.
* 不会立即执行 而是通过调度器有序的在主线程被执行
* 显然是可以被加入back stack
**/
public abstract int commit();
/**
* 该方法是 commit的加强版 支持在activity非活跃状态下提交事物
**/
public abstract int commitAllowingStateLoss();
/**
* Transactions committed in this way may not be added to the
* FragmentManager's back stack
* 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack
**/
public abstract void commitNow();
/**
* 1类似commitNow();类似到什么程度呢?就是不会把fragment 加入fragment back stack栈。 看来是个加强版
* 2 the commit can be lost if the activity needs to later be restored from its state,
* 这个方法可以 在activity状态改变之后使用在activity非active状态的情况下是可以提交 并不会报错的
* 了解到 这个方法 提交的fragment是不会被添加到 FragmentManager's back stack
**/
public abstract void commitNowAllowingStateLoss();
切入点 1 异常点 2 进入commitNowAllowingStateLoss这个方法看看怎么写的
我们看注释只能知其表,想知其理就需要看FragmentTransaction
的实现类BackStackRecord
@Override
public int commit() {
return commitInternal(false);
}
@Override
public int commitAllowingStateLoss() {
return commitInternal(true);
}
@Override
public void commitNow() {
disallowAddToBackStack();
mManager.execSingleAction(this, false);
}
@Override
public void commitNowAllowingStateLoss() {
disallowAddToBackStack();
mManager.execSingleAction(this, true);
}
聪明的你已经看出来了 是否加入BackStack取决于disallowAddToBackStack();
方法:
@Override
public FragmentTransaction disallowAddToBackStack() {
if (mAddToBackStack) {
throw new IllegalStateException(
"This transaction is already being added to the back stack");
}
mAllowAddToBackStack = false;
return this;
}
看到了吗? 我的异常也是爆了这里有错误:disallowAddToBackStack(BackStackRecord.java:600) 和我的切入点1 吻合,只是这个异常写的让人无所适从。