hwr*_*kns 41 android android-fragments fragmentmanager android-savedstate onsaveinstancestate
我有时会看到以下用于提交的堆栈跟踪,当用户没有查看活动时(状态保存后)可能会发生这种情况:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
看看Android源代码,这很有意义:
private void checkStateLoss() {
        if (mStateSaved) {
            throw new IllegalStateException(
                    "Can not perform this action after onSaveInstanceState");
        }
        if (mNoTransactionsBecause != null) {
            throw new IllegalStateException(
                    "Can not perform this action inside of " + mNoTransactionsBecause);
        }
 }
现在,我想知道是否有任何方法(除了在(保存/恢复)InstanceState中存储类变量)以检查片段是否将以不合需要的状态提交,这样我可以存储事务以供日后使用在适当的时候提交.
azi*_*ian 45
从支持库版本26.0.0 Beta 1开始,新的API可用于FragmentManager和Fragment类:
FragmentManager和Fragment有一个isStateSaved()方法,允许查询是否允许事务而不会丢失状态.这在检查在执行任何事务之前处理onClick()事件时特别有用.
来自以下的文档android.support.v4.app.FragmentManager#isStateSaved():
如果FragmentManager的状态已被其主机保存,则返回true.如果此方法返回true,则不应执行任何将更改已保存状态的操作.例如,任何popBackStack()方法,如popBackStackImmediate()或任何FragmentTransaction使用提交()代替commitAllowingStateLoss()将改变状态,并会导致一个错误.
此API android.app.FragmentManager将从Android O开始提供框架.
Tom*_*omo 19
由于您没有附加任何示例代码,我只能猜测您在提交事务时使用的是"错误"方法.
因此,FragmentTransaction.commit()您应该使用 
 FragmentTransaction.commitAllowingStateLoss()而不是使用它.
此外,此google博客文章中有关于此问题(或更改API行为)的报告和变通方法.
pea*_*ion 13
不幸的是,如果提交事务没有问题,Android Fragment不会提供API检查.
但是我们可以在附加的活动中添加一个布尔字段来帮助我们检查.请参考以下代码.
public class GlobalBaseActivity extends FragmentActivity {
    private boolean mAllowCommit;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAllowCommit = true;
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        mAllowCommit = false;
        super.onSaveInstanceState(outState);
    }
    @Override
    protected void onResumeFragments() {
        mAllowCommit = true;
        super.onResumeFragments();
    }
    public boolean allowFragmentCommit() {
        return mAllowCommit;
    } 
    public void callbackOnEvent() {
        if (allowFragmentCommit()){
            getFragmentManager().beginTransaction().add(new YourFragment(), TAG).commit();
        }
    }
}
至于为什么选择onResumeFragment()允许交易指标,请参考这个好博客.它详细解释了着名的IllegalStateException.
| 归档时间: | 
 | 
| 查看次数: | 19458 次 | 
| 最近记录: |