3

以前,我们显示以下内容没有问题DialogFragment

在此处输入图像描述

// Triggered by button click.
private void openFromCloud() {      
    LoadFromCloudTaskFragment loadFromCloudTaskFragment = new LoadFromCloudTaskFragment();
    FragmentManager fm = this.getSupportFragmentManager();
    fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commit(); 
}

DialogFragment但是,如果我们在下面按 OK 按钮后倾向于显示相同的内容Intent,则会出现错误。

在此处输入图像描述

private void openFromCloud() {      
    startActivityForResult(Utils.getGoogleAccountCredential().newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}

@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
    case REQUEST_ACCOUNT_PICKER:
        if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
            String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            if (accountName != null) {
                Utils.getGoogleAccountCredential().setSelectedAccountName(accountName);
                LoadFromCloudTaskFragment loadFromCloudTaskFragment = new LoadFromCloudTaskFragment();
                FragmentManager fm = getSupportFragmentManager();
                fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commit();
            }
        }
    break;
    }
}

这是详细的错误日志

FATAL EXCEPTION: main
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { (has extras) }} to activity {org.yccheok.xxx.gui/org.yccheok.xxx.gui.XXXFragmentActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3141)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3184)
    at android.app.ActivityThread.access$1100(ActivityThread.java:130)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1243)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4745)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
    at org.yccheok.xxx.gui.XXXFragmentActivity$1.run(XXXFragmentActivity.java:107)
    at android.app.Activity.runOnUiThread(Activity.java:4591)
    at org.yccheok.xxx.gui.XXXFragmentActivity.onActivityResult(XXXFragmentActivity.java:102)
    at android.app.Activity.dispatchActivityResult(Activity.java:5192)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3137)
    ... 11 more

commitAllowingStateLoss我可以通过使用而不是简单地“解决”问题commit

fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commitAllowingStateLoss();

我不太了解有关commitAllowingStateLoss.

与 commit() 类似,但允许在保存活动状态后执行提交。这是危险的,因为如果活动需要稍后从其状态恢复,提交可能会丢失,因此这应该只用于 UI 状态可以在用户上意外更改的情况。

这是基于获取异常“IllegalStateException:onSaveInstanceState 后无法执行此操作”的建议

我真的不明白UI 状态在用户身上意外改变是可以的。? 我可以知道使用可能的副作用是commitAllowingStateLoss什么吗?我可以产生这种副作用的任何步骤吗?

4

3 回答 3

5

我唯一能想到的就是一种“比赛条件”事件。

commitAllowingStateLoss()想象一种情况,当设备在您通话之前旋转。AFAIK,发生以下情况:

  • onSaveInstanceState()回调(活动存储它的状态,目前没有片段存在(因为你还没有提交任何东西)
  • commitAllowingStateLoss执行向活动添加片段
  • Activity重新创建,将其状态恢复到没有添加片段的那一刻

在我看来,它会导致难以预测的情况,例如:

  • java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentA如果您Fragment.setTargetFragment()出于任何原因使用
  • 您的片段可能只是从视图中丢失

无论如何,我对此不是 100% 确定的,但是我的java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState应用程序中有很多意外的异常,并且也试图找到解决方案。

于 2013-03-13T23:30:11.493 回答
2

可能你已经没有这个问题了。我遇到了类似的问题。我解决了将片段转换代码放在 onResume 函数中的问题。我放了一个标志来表明结果是否正常。如果这是真的,那么在 onResume 方法中我确实过渡到了其他片段。

于 2013-07-22T21:01:03.853 回答
0

可以在Activity.java中看到如下代码

 protected void onSaveInstanceState(Bundle outState) {
    outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
    Parcelable p = mFragments.saveAllState();
    if (p != null) {
        outState.putParcelable(FRAGMENTS_TAG, p);
    }
    getApplication().dispatchActivitySaveInstanceState(this, outState);
}

关键代码 ===>mFragments.saveAllState()

如果你在 onSaveInstanceState 之后提交,那么片段的状态将不会被保存

于 2015-10-14T08:39:57.503 回答