何时使用FragmentManager.isDestroyed()?为了避免IllegalStateException?

时间:2015-09-28 01:07:01

标签: android fragmentmanager

我的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吗?

2 个答案:

答案 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();
    }