75

我有一个LoginActivity(用户登录)。它基本上是它自己Activity的主题,就像一个对话框(看起来好像一个对话框)。它出现在一个SherlockFragmentActivity. 我想要的是:如果登录成功,应该有两个FragmentTransaction更新视图。这是代码:

LoginActivity,如果登录成功,

setResult(1, new Intent());

SherlockFragmentActivity

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == 1) {
        LoggedStatus = PrefActivity.getUserLoggedInStatus(this);
        FragmentTransaction t = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mFrag = new MasterFragment();
        t.replace(R.id.menu_frame, mFrag);
        t.commit();

        // Set up Main Screen
        FragmentTransaction t2 = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
        SherlockListFragment mainFrag = new FeaturedFragment();
        t2.replace(R.id.main_frag, mainFrag);
        t2.commit();
    }
}

它在第一次提交时崩溃,使用这个 LogCat:

E/AndroidRuntime(32072): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E/AndroidRuntime(32072):    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E/AndroidRuntime(32072):    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E/AndroidRuntime(32072):    at com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243)
E/AndroidRuntime(32072):    at android.app.Activity.dispatchActivityResult(Activity.java:5293)
E/AndroidRuntime(32072):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
4

5 回答 5

298

首先,您应该阅读我的博客文章以获取更多信息(它讨论了为什么会发生此异常以及您可以采取哪些措施来防止它)。

打电话commitAllowingStateLoss()更像是一种破解而不是修复。状态损失是不好的,应该不惜一切代价避免。在onActivityResult()调用时,活动/片段的状态可能尚未恢复,因此在此期间发生的任何事务都将因此丢失。这是一个非常重要的错误,必须解决!(请注意,该错误仅在您Activity被系统杀死后回来时才会发生……这取决于设备的内存量,有时可能很少见……所以这种错误不是测试时很容易捕捉到)。

尝试将您的事务移入onPostResume()(请注意,onPostResume()总是在之后调用onResume()并且onResume()总是在之后调用onActivityResult()):

private boolean mReturningWithResult = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mReturningWithResult = true;
}

@Override
protected void onPostResume() {
    super.onPostResume();
    if (mReturningWithResult) {
        // Commit your transactions here.
    }
    // Reset the boolean flag back to false for next time.
    mReturningWithResult = false;
}

这可能看起来有点奇怪,但是这样做是必要的,以确保在' 状态恢复到其原始状态FragmentTransaction始终提交您的 s (保证在 ' 状态恢复后调用) .ActivityonPostResume()Activity

于 2013-08-20T22:20:54.053 回答
1

这类似于@Alex Lockwood 的答案,但使用的是Runnable

private Runnable mOnActivityResultTask;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mOnActivityResultTask = new Runnable() {
        @Override
        public void run() {
            // Your code here
        }
    }
}

@Override
protected void onPostResume() {
    super.onPostResume();
    if (mOnActivityResultTask != null) {
        mOnActivityResultTask.run();
        mOnActivityResultTask = null;
    }
}

如果您使用lambdas运行Android 3.0及更高版本,请使用以下命令:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mOnActivityResultTask = () -> {
        // Your code here
    }
}
于 2017-09-22T20:54:18.090 回答
-1

你可以用它ft.commitAllowingStateLoss()来解决这个问题。

原因:您的ft.commit()方法在onSaveInstanceState.

于 2013-05-16T03:43:52.203 回答
-1

您的 logcat 清楚地表示:“在 onSaveInstanceState 之后无法执行此操作” -您Activity此时已经死了,无法返回任何结果。

移动:

Intent in = new Intent();
setResult(1, in);

到你Activity还活着的地方,一切都会好起来的。并且不要忘记向finish()Activity提供结果。

于 2013-04-28T17:46:50.223 回答
-1

就我而言,由于以下原因,我遇到了同样的问题

public void onBackPressed() {
    super.onBackPressed();
    setIntents();

}


private void setIntents(){
    Intent searchConstaints=new Intent();
    searchConstaints.putExtra("min",20);
    searchConstaints.putExtra("max",80);
    setResult(101,searchConstaints);
    finish();
}

通过在onBackPressed()中重新安排函数调用来解决

public void onBackPressed() {

    setIntents();
    super.onBackPressed();

}
于 2017-04-04T07:26:51.790 回答