当按BACK按钮时,setResult不起作用


111

我试图在按下BACK按钮后设置setResult。我打电话给onDestroy

Intent data = new Intent();
setResult(RESULT_OK, data) 

但是当涉及到

onActivityResult(int requestCode, int resultCode, Intent data) 

结果代码为0(RESULT_CANCELED),数据为“空”。

那么,如何传递以“返回”按钮终止的活动的结果?

Answers:


159

您需要在调用超类之前覆盖该onBackPressed()方法并设置结果,即

@Override
public void onBackPressed() {
    Bundle bundle = new Bundle();
    bundle.putString(FIELD_A, mA.getText().toString());
    
    Intent mIntent = new Intent();
    mIntent.putExtras(bundle);
    setResult(RESULT_OK, mIntent);
    super.onBackPressed();
}

23
请注意,如果使用这种方法,则在调用setResult()之后必须进行super.onBackPressed()调用,如上所示,否则您将再次遇到原始问题!
jengelsma

1
这是最好的答案。如果我们重写onPause()或onDestroy(),则会先调用onBackPressed()并将其设置为0。请注意!
Marek

或者您可以在onCreate中设置默认结果。finish()之前的任何地方都可以。
Helin Wang 2013年

5
我实现了类似的方法,但仍然无法正常工作。比如我有请求代码和意图工作,但resultCode为始终为0
氖Warge

68

Activity必须 finish()调用之前设置结果。单击后退实际上是调用finish()你的activity,所以你可以使用下面的代码片段:

@Override
public void finish() {
    Intent data = new Intent();
    setResult(RESULT_OK, data); 

    super.finish();
}

如果你打电话NavUtils.navigateUpFromSameTask();onOptionsItemSelected()finish()是所谓的,但你会得到错误的result code。因此,您必须finish()navigateUpFromSameTask打入onOptionsItemSelected()onActivityResult中的requestCode错误


这在OP的情况下有效,但总的来说不是吗?除了finish()之外,还有更多方法可以导致应用程序生命周期的结束(通过onPause()和onDestroy())?另请参阅我在其他答案上的评论。
pjv 2011年

而且即使没有,您也不会知道何时将其引入API更新中。不像onPause()或onDestroy()的行为更改时那样容易。这些是您应该覆盖的方法。
pjv 2011年

6
@pjv-我不明白你的意思,finishonPause和有什么关系onDestroy?这些是完全没有关系的除外finish开始终止的过程,onPause并且onDestroy是一部分。
JBM

20

如果您想RESULT_CODEonBackPressed事件中设置一些自定义,则需要先设置result,然后调用,super.onBackPressed()然后您将RESULT_CODE在调用者活动的onActivityResult方法中收到相同的信息

    @Override
    public void onBackPressed()
    {
         setResult(SOME_INTEGER);
         super.onBackPressed();
    }

10

我重构了代码。起初,我准备了一些数据,并将其设置为activity resultonDestroy(这不工作)。现在,activity每次更新要返回的数据时,我都设置了数据,而中没有任何内容onDestroy


这并不为我工作,因为我的数据是更新的“的onPause”
Bostone

如果在致电后重新创建活动setResult(),则数据将丢失。
贾里特·米拉德

3

您应该像这样覆盖onOptionsItemSelected

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        final Intent mIntent = new Intent();
        mIntent.putExtra("param", "value");
        setResult(RESULT_OK, mIntent);
        finish();
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

2

请参阅onActivityResult(int,int,Intent)文档

解决方案是检查resultCode的值Activity.RESULT_CENCELED。如果是,则表示按下了BACK或活动崩溃。希望它对你们有用,对我有用:)。


这是确切的解决方案。您必须输入结果代码。除了您在代码中之外,没有人可以设置结果。因此,如果结果不正确,则意味着其后推或摔坏。.–
John

0

onDestroy在链中为时已晚-请覆盖onPause并检查isFinishing()您的活动是否处于生命周期的尽头。


1
不,这也为时已晚。
alex2k8'4

我实际上将此称为错误:code.google.com/p/android/issues/detail?id=1671。由于这种原因,我认为在复杂的应用程序中,只有某些行为无法编程。
2011年

这也是非常违反直觉的。如此之多,以至于我在两年的时间内一直犯同样的错误。
pjv 2011年

实际上-这甚至更糟。在我编写代码时,它存在于JB中。如果我从onPause调用setResult,则将执行它,但是在执行onActivityReturn时,将设置resultCode或数据。为什么?
波士顿

这就是为什么:“此方法(onPause)的实现必须非常快,因为在此方法返回之前,下一个活动将不会恢复” goo.gl/8S2Y
Bostone,2012年


0

当您返回初始活动时,不要依赖在一个活动的onPause中执行的任何逻辑。根据文档:

此方法的实现(onPause)必须非常快,因为在此方法返回之前,下一个活动将不会恢复

参见http://goo.gl/8S2Y详情,。

最安全的方法是在每次结果更改操作完成后设置结果(如您在回答中所述)


0

我粘贴答案可能对其他人会有所帮助:当设置了带有android:launchMode =“ singleTask”的launcheMode时,我也无法获得结果,医生说:

     /* <p>Note that this method should only be used with Intent protocols
 * that are defined to return a result.  In other protocols (such as
 * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
 * not get the result when you expect.  For example, if the activity you
 * are launching uses the singleTask launch mode, it will not run in your
 * task and thus you will immediately receive a cancel result.
 */

和:

     /* <p>As a special case, if you call startActivityForResult() with a requestCode 
 * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
 * activity, then your window will not be displayed until a result is 
 * returned back from the started activity.  This is to avoid visible 
 * flickering when redirecting to another activity. 
 */
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.