"未能提供结果" - onActivityForResult

The*_*ter 72 android android-intent android-activity android-fragmentactivity

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

LoginActivity,如果成功登录,

setResult(1, new Intent());
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

它在第一次提交时崩溃,使用此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)
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 289

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

呼叫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;
}
Run Code Online (Sandbox Code Playgroud)

这似乎有点不可思议,但在做这样的事情是必要的,以确保您FragmentTransactions的始终致力于Activity的状态已经恢复到原来的状态(onPostResume()是保证之后调用Activity的状态有所恢复) .

  • 是的,在`Fragment#onResume()`中这样做很好.这是因为`FragmentActivity#onPostResume()`调用`FragmentActivity#onResumeFragments()`,它调用`FragmentManager#dispatchResume()`,它为每个活动的片段调用`Fragment#onResume()`.因此,`Fragment#onResume()`在`FragmentActivity#onPostResume()之后调用`所以不会有问题(你可以查看[源代码](http://goo.gl/Lo1Z1T)各自的班级为自己验证这个...或者你可以只是我:P).谢谢!很高兴你认为他们很有见地.:) (27认同)
  • 在Fragments中,我在没有onPostResume的情况下使用onResume.我没有再看过这个问题,但也许你想对此发表评论.PS.非常感谢您的精彩帖子! (4认同)
  • @crazyhorse在这种情况下,取消异步任务和/或引发一个标志以确保在`AsyncTask#onPostExecute()`中不调用`dismiss()`可能是一个好主意(对话框将自动被解除)在活动进入后台的情况下,通过`FragmentManager`,所以在活动消失之后你不需要自己解除对话框). (2认同)