49

实现用户可以登录的应用程序我有以下情况:如果用户已登录,则执行操作,否则启动登录活动以获得结果,如果结果是 Activity.RESULT_OK 则执行操作。

我的问题是要执行的操作是显示 DialogFragment,但调用

DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
newFragment.show(ft, "dialog")

在 onActivityResult 回调中抛出异常:

Caused by: java.lang.IllegalStateException:  
Can not perform this action after onSaveInstanceState

那么我该如何解决呢?我正在考虑在那里升旗并在 onResume 中显示对话框,但我认为这个解决方案有点脏

编辑:添加了更多代码(我按照此示例显示DialogFragment

当用户请求操作时:

... 
if (!user.isLogged()){
 startActivityForResult(new Intent(cnt, Login.class), REQUEST_LOGIN_FOR_COMMENT);
}

在同一个片段

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_LOGIN_FOR_COMMENT && resultCode == Activity.RESULT_OK) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        DialogFragment newFragment = MyDialogFragment.newInstance();
        newFragment.show(ft, "dialog")
    }
}

如果用户登录登录活动调用;

setResult(Activity.RESULT_OK);
finish();
4

8 回答 8

102

我想出的最好的事情是不使用 .show() 而是这样做。

CheckinSuccessDialog dialog = new CheckinSuccessDialog();
//dialog.show(getSupportFragmentManager(), null);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(dialog, null);
ft.commitAllowingStateLoss();
于 2012-09-17T18:11:17.680 回答
14

这是适合我的解决方法。

private void alert(final String message) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance(message);
            alertDialogFragment.show(getFragmentManager(), ALERT_DIALOG_FRAGMENT);
        }
    });        
}
于 2013-05-31T14:11:45.310 回答
4

如果使用 DialogFragment,唯一对我有用的是使用 dissmissAllowingStateLoss() 关闭 Fragment

于 2014-02-11T12:15:56.283 回答
4

我只是检查一个活动是否被破坏。

if (!getActivity().isFinishing()) {
    DialogFragment fragment = MyFragment.newInstance();
    fragment.show(getActivity().getSupportFragmentManager(), MyFragment.TAG);
}

另请参阅https://stackoverflow.com/a/41813953/2914140。在DialogFragment写:

override fun show(manager: FragmentManager?, tag: String?) {
    try {
        val ft = manager?.beginTransaction()
        ft?.add(this, tag)
        ft?.commitAllowingStateLoss()
    } catch (ignored: IllegalStateException) {
    }
}
于 2016-09-24T20:21:40.840 回答
2

通过反射show(Fragment manager, String tag)允许状态丢失和从原始函数更改的覆盖函数:mDismissed = false; mShownByMe = true;

public class DialogParent extends DialogFragment {

    @Override
    public void show(FragmentManager manager, String tag) {
        try {
            Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
            Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
            mDismissed.setAccessible(true);
            mShownByMe.setAccessible(true);
            mDismissed.setBoolean(this, false);
            mShownByMe.setBoolean(this, true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        FragmentTransaction ft = manager.beginTransaction();
        ft.add(this, tag);
        ft.commitAllowingStateLoss();
    }
}
于 2016-12-12T07:59:21.090 回答
0

这真的有效。

CheckinSuccessDialog dialog = new CheckinSuccessDialog();
//dialog.show(getSupportFragmentManager(), null);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(dialog, null);
ft.commitAllowingStateLoss();

但仍然很糟糕,因为出现错误“活动已被破坏”</p>

ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss();

所以我的解决方案是添加检查if (!isFinishing()&&!isDestroyed())

CheckinSuccessDialog fragment = CheckinSuccessDialog.newInstance();

     if (fragment instanceof DialogFragment) {
                DialogFragment dialog = (DialogFragment) fragment;
                if (!dialog.isAdded()) {
                    fragmentTransaction.add(dialog, 
                          CheckinSuccessDialog.class.getName());
                    if (!isFinishing()&&!isDestroyed()) {
                        fragmentTransaction.commitAllowingStateLoss();
                    }
                }

解雇时:

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        Fragment fragment = getSupportFragmentManager().findFragmentByTag(CheckinSuccessDialog.class.getName());
        if (fragment != null && fragment instanceof DialogFragment) {
            DialogFragment dialog = (DialogFragment) fragment;
            dialog.dismiss();
            if (!isFinishing()&&!isDestroyed()) {
                fragmentTransaction.commitAllowingStateLoss();
            }
        }
于 2017-05-13T16:19:41.763 回答
0

每当 a 在保存其状态FragmentTrasaction后提交时,都会引发此异常。FragmentManager简单而干净的方法是FragmentManager在显示之前检查是否已经保存状态DialogFragment

if(!getSupportFragmentManager.isStateSaved()) {
    MyDialogFragment dialogFragment = new MyDialogFragment()
    dialogFragment.show(getSupportFragmentManager, TAG);
}
于 2017-11-29T05:58:54.483 回答
0

您应该super.onActivityResult()在显示对话框之前调用

于 2021-10-24T03:31:44.083 回答