commitAllowingStateLoss

commitAllowingStateLoss

以前,我们在显示以下DialogFragment

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

但是,如果在按下下面的“确定”按钮后,我们倾向于显示相同的DialogFragment,则会发生错误。
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

我可以用Intent而不是commitAllowingStateLoss来“解决”这个问题。
fm.beginTransaction().add(loadFromCloudTaskFragment, "loadFromCloudTaskFragment").commitAllowingStateLoss();

我不太了解有关commit的文档。
与commit()类似,但允许在活动的
状态已保存。这很危险,因为如果
活动稍后需要从其状态恢复,因此
仅用于用户界面状态可以更改的情况
对用户意外。
这是基于getting exception "IllegalStateException: Can not perform this action after onSaveInstanceState"的建议
我真的不明白,用户界面的状态可以在用户身上意外地改变。我能知道使用commitAllowingStateLoss可能有什么副作用吗?我有没有办法产生这种副作用?

最佳答案

我唯一能想到的,就是那种“比赛状态”的比赛。
想象一下,当设备在您的commitAllowingStateLoss()调用之前旋转时的情况。afaik,发生以下情况:
onSaveInstanceState()回调(activity store当前状态没有片段(因为您还没有提交任何内容)
commitAllowingStateLoss在向活动添加片段时执行
Activity被重新创建,将其状态恢复到没有添加片段时的状态
在我看来,这种情况很难预测,例如:
java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentA如果您出于任何原因使用Fragment.setTargetFragment()
您的片段可能只是从视图中丢失了
无论如何,我不能百分之百确定,但我的应用程序中有很多意外的java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState异常,我也在试图找到解决方案。

10-05 19:18