我的Activity中有一个监听器,在另一个线程上完成网络请求后替换Fragment。所以这个监听器正在调用一行代码:
getFragmentManager().beginTransaction().replace(R.id.container, fragment, fragmentTag).commit();
此行代码中的commit()偶尔会抛出IllegalStateException。根据{{3}},
事务只能在其包含活动保存其状态之前使用此方法提交。如果在该点之后尝试提交,则将引发异常。这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失。有关可能丢失提交的情况,请参阅commitAllowingStateLoss()。
在调查此问题时,我遇到了the docs方法。 javadocs读到:
如果对FragmentManager的Activity进行了最后的Activity.onDestroy()调用,则返回true,因此该实例现已停止。
我想我对FragmentManager的Activity实例死机的含义感到有些困惑。我们什么时候应该使用FragmentManager.isDestroyed()?在提交替换FragmentTransaction之前检查它会避免IllegalStateException吗?
答案 0 :(得分:1)
我的代码如下所示。执行时,显示工作和我想要的片段,或者我得到日志消息,表明.isDestroyed()是真的。如果我删除.isDestroyed()上的检查,那么ft.commit()
将抛出IllegalStateException。
这种解决方案可以防止由此造成的崩溃,但它并不一定能解决为什么它首先出现的潜在时间问题。
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragementTransaction;
public class CallingCard extends Fragment
{
// ... some stuff for my fragment ...
}
public class MyFragment extends Fragment
{
public void showCallingCard() {
CallingCard callingCard = new CallingCard();
FragmentManager fm = parent.getSupportFragmentManager();
// ensure serialization of fragment transactions
fm.executePendingTransactions();
if (!fm.isDestroyed()) {
// attempt to display fragment
FragementTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragPlaceHolder, callingCard);
ft.commit();
} else {
Log.e("tag", "fm.isDestroyed() was true");
}
}
}
答案 1 :(得分:0)
保持一个标志以了解活动的当前状态。检查onPause状态。
在活动进入onPause状态后,不要进行片段管理器事务。这为我工作.. !!!
@Override
protected void onPause() {
super.onPause();
isPaused = true;
}
@Override
protected void onResume() {
super.onResume();
isPaused = false;
}
//检查isPaused标志。
if (!isPaused) {
fragmentManager.popBackStack(fragment.getClass().getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction()
// .setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out)
.replace(R.id.container, fragment)
.commitAllowingStateLoss();
}