"未交付成果和QUOT; - onActivityForResult [英] "Failure Delivering Result " - onActivityForResult

查看:164
本文介绍了"未交付成果和QUOT; - onActivityForResult的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 LoginActivity (用户登录)。它基本上是自己的活动的主题是像一个对话框(显示为如果一个对话框)。这似乎在一个 SherlockFragmentActivity 。我要的是:如果有一个成功登录,应该有两个 FragmentTransaction 的更新视图。这里是code:

LoginActivity ,如果登录成功,

 的setResult(1,新意图());
 

SherlockFragmentActvity

  @覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    super.onActivityResult(要求code,因此code,数据);

    如果(结果code == 1){
        LoggedStatus = prefActivity.getUserLoggedInStatus(本);
        FragmentTransaction T = MainFragmentActivity.this.getSupportFragmentManager()的BeginTransaction()。
        SherlockListFragment mFrag =新MasterFragment();
        t.replace(R.id.menu_frame,mFrag);
        t.commit();

        //设置主屏幕
        FragmentTransaction T2 = MainFragmentActivity.this.getSupportFragmentManager()的BeginTransaction()。
        SherlockListFragment mainFrag =新FeaturedFragment();
        t2.replace(R.id.main_frag,mainFrag);
        t2.commit();
    }
}
 

据死机就第一次提交,这个LogCat中:

  E / AndroidRuntime(32072):java.lang.IllegalStateException:产生的原因不能的onSaveInstanceState后执行此操作
E / AndroidRuntime(32072):在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E / AndroidRuntime(32072):在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E / AndroidRuntime(32072):在android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E / AndroidRuntime(32072):在android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E / AndroidRuntime(32072):在com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243)
E / AndroidRuntime(32072):在android.app.Activity.dispatchActivityResult(Activity.java:5293)
E / AndroidRuntime(32072):在android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
 

解决方案

首先,你应该读我的<一个href="http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html">blog交 以了解更多信息(它谈论为什么这种异常情况,什么可以做,以prevent它)。

调用 commitAllowingStateLoss()更是一个黑客不是固定的。国家的损失是坏的,应该不惜一切代价避免。当时的 onActivityResult()被调用时,活动/片段的状态可能还没有得到恢复,因此在这个时候,发生的任何交易都将丢失,结果。这是必须解决的一个非常重要的错误! (请注意,当你的活动是已被打死的系统......这,这取决于设备的内存有后回来的错误仅发生,有时会难得......所以这种错误是不是一件很容易赶上,而测试)。

尝试将你交易到 onPostResume()代替(注意, onPostResume()总是被调用后, onResume() onResume()总是被调用后 onActivityResult()

 私人布尔mReturningWithResult = FALSE;

@覆盖
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
    super.onActivityResult(要求code,因此code,数据);
    mReturningWithResult = TRUE;
}

@覆盖
保护无效onPostResume(){
    super.onPostResume();
    如果(mReturningWithResult){
        //这里提交你的事务。
    }
    //重新设置布尔标志为false为下一次。
    mReturningWithResult = FALSE;
}
 

这似乎有点不可思议,但在做这样的事情是要确保你的 FragmentTransaction s的始终致力于的的的活动的状态已经恢复到原来的状态( onPostResume()被担保的<$ C被称为$ C>活动的状态有所恢复)

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 code:

In LoginActivity, if successful login,

setResult(1, new Intent());

In SherlockFragmentActvity:

@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();
    }
}

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).

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).

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;
}

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).

这篇关于&QUOT;未交付成果和QUOT; - onActivityForResult的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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