onActivityResult() 被过早调用

93

我从我的工作活动中启动Activity(PreferenceActivity的后代)如下:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1458)
        loadInfo();
}

void showSettingsDialog()
{
    startActivityForResult(new Intent().setClass(this, MyConfigure.class), 1458);
}

MyConfigure类没有任何setResult()调用。实际上,MyConfigure类除了使用addPreferencesFromResource加载偏好设置的OnCreate()以外没有任何代码。

现在,在运行MyConfigure活动后立即使用1458requestCode调用onActivityResult。在1.6和2.1模拟器以及2.1设备上进行了测试。在PreferenceActivity中是否有setResult()的调用?或者还有其他什么原因可以解释这个过早的调用?


1
一个活动不会在setResults()上结束,它会在finish()上结束。你能展示一下你的MyConfigure活动的onCreate方法吗? - Cheryl Simon
没错,确实没有。但是有些东西会提前调用setResult(),我想知道是什么。onCreate的代码很简单:public class MyConfigure extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } - Eugene Mayevski 'Callback
你认为如何知道setResult被调用了? - RoflcoptrException
这正是我创建这个问题的原因。为了找出为什么onActivityResult会过早调用。 - Eugene Mayevski 'Callback
在这段时间内,logcat输出显示了什么?特别是“ActivityManager”标签,它显示了哪些意图正在被调用。 - Christopher Orr
还有其他人在使用singleTop启动模式时遇到了这个问题吗?我刚刚遇到了这个问题,可能需要在被启动的活动中硬编码一些内容 - 所以如果有人找到了解决方法,请告诉我(在Nexus 7上使用Android 4.2.2)。 - nikib3ro
5个回答

258

将启动模式更改为singleTop即可解决此问题:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop">

在Android中存在一个bug/特性,它会立即报告作为singleTask声明的Activity的结果(尽管该Activity仍在运行中,结果尚未设置)。如果我们将父Activity的launchMode从singleTask更改为singleTop,则一切都按预期工作 - 结果仅在Activity完成后报告。虽然这种行为有一定的解释(只能存在一个singleTask活动,并且可能会发生多个等待者),但对我来说仍然是一个不合逻辑的限制。


2
好像是个bug!^^非常奇怪的行为! - Felipe
7
如果活动具有 singleTask 启动模式,则不需要使用 onActivityResult 从子活动接收结果。子活动只需调用 finish(),然后使用数据意图启动主活动。在主活动中,您必须重写 onNewIntent 方法并处理接收到的意图。 - Nik
43
launchMode="singleInstance" 也会导致这种行为。 - ffleandro
1
似乎这对我没有起作用,我在父活动上尝试了singleTop但无济于事。我还将意图标志设置为FLAG_ACTIVITY_SINGLE_TOP,虽然请求现在显示正确的值,但结果始终为0。 - Neon Warge
11
它发生在安卓4.4.4 KitKat版本,而在Lollipop版本中并未发生。 - Somasundaram Mahesh
显示剩余12条评论

20

在调用fragment.startActivityForResult(intent, 0);之前,我删除了intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);来解决我的问题。


1
谢谢!这解决了我的问题。有没有相关的解释? - Conner Harkness
现在的文档中对此进行了解释,“当调用者请求从被启动的活动中获取结果时,不能使用这个标志。”虽然这不算是一种解释,但至少是一个警告! - Pure Function

5
我刚刚从我的 Activity 中删除了所有自定义的 "android:launchMode",结果一切顺利。如果您不确定 Android 的确切理解方式,更改此设置并不是一个好主意。在这方面,Android 有点棘手。

1
当意图具有Intent.FLAG_RECEIVER_FOREGROUND标志时,这种情况发生在我身上。
(是的,那个标志与活动无关,但作为解决另一个问题的一部分,我将其应用于所有意图中。)

-1

就像Mayra的评论中所说,setResult()与您的问题无关。由于某种原因,MyConfigure类自己完成了,当它发生时,PreferenceActivity只是假设可能会有来自MyConfigure的结果,因为这是您编写代码的方式。

当您强制返回使用startActivityForResult()启动的任何活动时,也会发生这种情况...

因此,我认为更好的方法是集中精力解决您的MyConfigure类被强制完成的原因。


我的MyConfigure类没有完成,你的猜测是错误的,抱歉。如果它完成了,就不会有问题了。 - Eugene Mayevski 'Callback

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接