93

I start the Activity (descendant of PreferenceActivity) from my worker activity as follows:

@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 class does NOT have any setResult() calls. In fact, MyConfigure class doesn't have any code except OnCreate() where it loads preferences using addPreferencesFromResource.

Now onActivityResult is called with requestCode of 1458 prematurely, right after MyConfigure activity is run. Tested on 1.6 and 2.1 emulators as well as 2.1 device. Is there a call to setResult() buried somewhere in PreferenceActivity? Or how else can this premature call be explained?

fawaad
  • 341
  • 6
  • 12
Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • 1
    An activity doesn't end on setResults(), it ends on finish(). Can you show the onCreate method of your MyConfigure activity? – Cheryl Simon Jul 28 '10 at 16:24
  • Right, it doesn't. However, something does call setResult() ahead of time and I am wondering, what it is. The code of onCreate is trivial: public class MyConfigure extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } – Eugene Mayevski 'Callback Jul 28 '10 at 17:02
  • how do you think to know that setResult is called? – RoflcoptrException Jul 28 '10 at 17:05
  • That is exactly what I created the question for. To find out, why onActivityResult is called prematurely. – Eugene Mayevski 'Callback Jul 28 '10 at 17:18
  • What does the logcat output say around this period? Specifically the "ActivityManager" tag, which shows which Intents are being called. – Christopher Orr Jul 29 '10 at 08:31
  • Is anyone else experiencing this problem when both activities (the one that's launching and the one that's being launched) are singleTop? I'm just experiencing that and will probably need to hardcode something in launched activity - so let me know if someone found some workaround (working on Android 4.2.2 on Nexus 7). – nikib3ro Mar 27 '13 at 20:14

5 Answers5

258

This is fixed by changing the launch mode to singleTop:

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

There's a bug / feature (?) in Android, which immediately reports result (which has not been set yet) for Activity, declared as singleTask (despite the fact that the activity continues to run). If we change launchMode of the parent activity from singleTask to singleTop, everything works as expected - result is reported only after the activity is finished. While this behavior has certain explanation (only one singleTask activity can exist and there can happen multiple waiters for it), this is still a not logical restriction for me.

fawaad
  • 341
  • 6
  • 12
Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • 2
    It seems a bug! ^^ very weird behavior! – Felipe Oct 10 '11 at 22:26
  • 7
    If activity has singleTask launch mode it not need to receive results from sub-activityes using onActivityResult. Sub-activityes just call finish() and then start main activity with data intent. In main activity you must override onNewIntent method and process received intent. – Nik Jun 07 '12 at 11:48
  • 43
    launchMode="singleInstance" also causes this behaviour – ffleandro Jun 01 '13 at 15:24
  • Worth nothing I needed SingleTop on my _parent_ activity, not just the child – jmaculate Jun 04 '14 at 19:58
  • I can't believe this bug, even in Android L Preview! Wasted hours trying to figure out what was going on until I came across this. +1 for the great explanation. – Apqu Aug 08 '14 at 10:44
  • The solution works but it is weird that adding FLAG_ACTIVITY_SINGLE_TOP to the intent did not produce the same effect. – Gilbou Aug 24 '14 at 09:48
  • @jmaculate this probably depends on your activity stack and OS version. – Eugene Mayevski 'Callback Dec 20 '14 at 09:16
  • Just removed the launchMode *singleTask* from the Activity that has to provide result data and it worked. THX – Yoraco Gonzales Mar 09 '15 at 05:45
  • 1
    It seems did this not work for me, I tried singleTop on parent activity but to no avail. I also set the intent flag into FLAG_ACTIVITY_SINGLE_TOP, though the request now shows the correct value but the result is always 0. – Neon Warge Apr 30 '15 at 07:57
  • 1
    @NeonWarge what Android version do you have? The issue exposes itself differently on different versions. The best you can do is open the source code of Android itself (as I did) and find out the reason of your problem in that way. – Eugene Mayevski 'Callback Apr 30 '15 at 19:44
  • I was doing min version = 8 and target SDK at 22. I fix the problem by circumventing that approach anyway. And most importantly, that silly mistake I made, I mixed request code with result code. They were on different param places. I didn't notice that. – Neon Warge Apr 30 '15 at 19:48
  • thanks! I'm using SDK 22, and support v4 fragment, it happened!. you save a lot of my time! – iroiroys Jul 01 '15 at 05:40
  • 11
    it happens on Kitkat 4.4.4, not happening on Lolipop. – Somasundaram Mahesh Oct 19 '15 at 15:38
  • The problem is the Activity I am launching is Searchable so I can't remove this flag otherwise it totally screws over the search processing. Back to square one without a solution. – Kevin Mar 01 '16 at 20:23
  • It works with all popular brand devices and all version. Saved my another day. Thank you very much. – Naitik Jul 27 '16 at 06:39
  • Didn't worj for me yet on Samsung running Kitkat. – sud007 Sep 22 '16 at 09:48
  • Single instance not working for me, some Samsung Galaxy Tablet API 19. Single top works – lawonga Jan 24 '17 at 01:31
20

I solved my problem after removing intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); before calling fragment.startActivityForResult(intent, 0);.

josliber
  • 43,891
  • 12
  • 98
  • 133
TPG
  • 2,811
  • 1
  • 31
  • 52
  • 1
    Thank you! This solved my problem. Is there an explanation for this somewhere? – Conner Harkness Apr 01 '17 at 15:53
  • There is an explanation for this in the docs for the flag these days "This flag can not be used when the caller is requesting a result from the activity being launched". Well its not an explanation but at least a warning! – Pure Function Mar 26 '20 at 21:42
5

I just removed all my custom "android:launchMode" from my Activity and everything worked like a charm. It is not a good idea change this when you don't know EXACTLY what Android is understanding... Android is a little tricky in this way.

Felipe
  • 16,649
  • 11
  • 68
  • 92
1

This happened to me when the intent had the Intent.FLAG_RECEIVER_FOREGROUND flag set.

(Yes, that flag isn't activity-related, but I had it on all my intents as part of a shotgun solution to a different problem.)

Sam
  • 40,644
  • 36
  • 176
  • 219
-1

Again as in Mayra's comment, setResult() has nothing to do with your problem. for some reason, MyConfigure class finishes itself and when it happens PreferenceActivity just assumes that there might be a result from MyConfigure because that's how you wrote the code.

this also happens when you force back any activity thats started with startActivityForResult()...

So, I think it's better to focus on why your MyConfigure class is forcibly finished.

fawaad
  • 341
  • 6
  • 12