“交付结果失败”-onActivityForResult

我有一个 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)
43968 次浏览

your logcat clearly says: "Can not perform this action after onSaveInstanceState" -- your Activity is already dead at that point and could not return any results.

just move:

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

to the place in your Activity where it's still alive, and everything will be fine. and don't forget to finish() your Activity to deliver the result.

You can use ft.commitAllowingStateLoss() to solve this problem.

Reason: your ft.commit() method was toggled after onSaveInstanceState.

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

In my Case I faced the same issues Because of the Following

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

Solved by re-arranging the function Calls within onBackPressed()

public void onBackPressed() {


setIntents();
super.onBackPressed();


}

This is similar to the @Alex Lockwood answer but using a 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;
}
}

In case you're running Android 3.0 and above with lambdas, use this:

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