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: Can not perform this action after onSaveInstanceState」の取得からの提案に基づいています。

ユーザーにとってUIの状態が予期せず変更されても問題ないという点がよくわかりません。? を使用した場合の副作用について教えてcommitAllowingStateLossください。そのような副作用を引き起こす可能性のある手順はありますか?

4

3 に答える 3

5

私が考えることができる唯一のことは、一種の「競合状態」イベントです。

commitAllowingStateLoss()通話の直前にデバイスが回転している状況を想像してください。私の知る限り、次のことが起こります。

  • onSaveInstanceState()コールバック(アクティビティは、現時点でフラグメントが存在しない状態を保存します(まだ何もコミットしていないため)
  • commitAllowingStateLossアクティビティにフラグメントを追加して実行されます
  • Activity再作成され、フラグメントが追加されなかった時点の状態に復元されます

私の意見では、次のようなほとんど予測できない状況を引き起こします。

  • java.lang.IllegalStateException: Failure saving state: FragmentB has target not in fragment manager: FragmentAFragment.setTargetFragment()何らかの理由で使用している場合
  • フラグメントが単にビューから欠落している可能性があります

とにかく、私はそれについて 100% 確信しているわけではありませんがjava.lang.IllegalStateException: Can not perform this action after onSaveInstanceState、アプリで予期しない例外がたくさんあり、解決策も見つけようとしています。

于 2013-03-13T23:30:11.493 に答える