《失败交付结果》- onActivityForResult [英] "Failure Delivering Result " - onActivityForResult

查看:20
本文介绍了《失败交付结果》- onActivityForResult的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a LoginActivity (User Logs in). It is basically its own Activity that is themed like a dialog (to appear as if a dialog). It appears over a SherlockFragmentActivity. What I want is: If there is a successful login, there should be two FragmentTransaction's to update the view. Here is the code:

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:

It crashes on the first commit, with this 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)

推荐答案

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

First of all, you should read my blog post for more information (it talks about why this exception happens and what you can do to prevent it).

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

Calling commitAllowingStateLoss() is more of a hack than a fix. State loss is bad and should be avoided at all costs. At the time that onActivityResult() is called, the activity/fragment's state may not yet have been restored, and therefore any transactions that happen during this time will be lost as a result. This is a very important bug which must be addressed! (Note that the bug only happens when your Activity is coming back after having been killed by the system... which, depending on how much memory the device has, can sometimes be rare... so this sort of bug is not something that is very easy to catch while testing).

尝试将您的交易转移到 onPostResume() 中(注意 onPostResume() 总是在 onResume() 之后调用)onResume() 总是在 onActivityResult()) 之后调用:

Try moving your transactions into onPostResume() instead (note that onPostResume() is always called after onResume() and onResume() is always called after 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 始终在 Activity提交>的状态已经恢复到原来的状态(onPostResume()保证在Activity的状态恢复后会被调用).

This might seem a little weird, but doing this sort of thing is necessary to ensure that your FragmentTransactions are always committed after the Activity's state has been restored to its original state (onPostResume() is guaranteed to be called after the Activity's state has been restored).

这篇关于《失败交付结果》- onActivityForResult的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆