当前位置 : 主页 > 手机开发 > android >

android – 使用commitAllowingStateLoss解决“无法在onSaveInstanceState之后执行此操作”的

来源:互联网 收集:自由互联 发布时间:2021-06-11
以前,我们在显示以下DialogFragment时没有问题 // Triggered by button click.private void openFromCloud() { LoadFromCloudTaskFragment loadFromCloudTaskFragment = new LoadFromCloudTaskFragment(); FragmentManager fm = this.getSuppor
以前,我们在显示以下DialogFragment时没有问题

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

但是,如果在按下以下Intent上的OK按钮后我们倾向于显示相同的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

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

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

我真的不了解有关commitAllowingStateLoss的文档.

Like commit() but allows the commit to be executed after an activity’s
state is saved. This is dangerous because the commit can be lost if
the activity needs to later be restored from its state, so this should
only be used for cases where it is okay for the UI state to change
unexpectedly on the user.

这是基于getting exception “IllegalStateException: Can not perform this action after onSaveInstanceState”的建议

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

我唯一能想到的是一种“竞争条件”事件.

想象一下在commitAllowingStateLoss()调用之前旋转设备的情况. AFAIK,发生以下情况:

> onSaveInstanceState()回调(活动存储它的状态,此刻没有片段存在(因为你还没有提交任何东西)
>执行commitAllowingStateLoss将片段添加到活动中
>重新创建活动,将状态恢复到当前没有添加任何碎片的状态

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

> java.lang.IllegalStateException:失败保存状态:如果您因任何原因使用Fragment.setTargetFragment(),FragmentB的目标不在片段管理器中:FragmentA
>您的片段可能只是从视图中丢失

无论如何,我对此并不是百分之百确定,但是我有很多意外的java.lang.IllegalStateException:在我的应用程序中的onSaveInstanceState异常之后无法执行此操作,并且也试图找到解决方案.

网友评论