FLAG_ACTIVITY_SINGLE_TOP is not overriding singleTask

343 Views Asked by At

I read through the standard documentation on Launch modes and it mentions,

As such, if Activity A starts Activity B, Activity B can define in its manifest how it should associate with the current task (if at all) and Activity A can also request how Activity B should associate with current task. If both activities define how Activity B should associate with a task, then Activity A's request (as defined in the intent) is honored over Activity B's request (as defined in its manifest).

I created an experiment to test this and here is how it goes,

I created 2 Activities - MainActivity(launcher activity) and Activity2:

        <activity
            android:name=".Activity2"
            android:exported="false"
            android:launchMode="singleTask"
            android:taskAffinity="com.affin_1"/>
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Note that the Activity has an explicitly defined affinity that is defined from the default one and also has a launch mode of singleTask.

In MainActivity's onCreate(), I launch Activity2 which should launch in a new task. It infact does as expected.

At this point, I am able to see 2 different tasks with Activity2 and MainActivity. Now, I introduce a button in MainActivity clicking which I launch Activity2 but a bit differently:

button.setOnClickListener {
            startActivity(Intent(this, Activity2::class.java)
                .setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
        }

I am setting launch flag for the intent. The expectation is that it will create a new Activity2 instance in the MainActivity's task as I expect the flag Intent.FLAG_ACTIVITY_SINGLE_TOP to override the manifest declared singleTask launch mode.

At the end, we will have 2 tasks:

  • Task1: MainActivity -> Activity2
  • Task2: Activity2

But this is not happening. Instead, the system is routing intent to the existing Activity2 in Task2. It is supposed to override the singleTask launch mode

You can find my experiment here: https://github.com/mankum93/LaunchModeExperiments

1

There are 1 best solutions below

0
David Wasser On

That's the way it should work!

You cannot override the singleTask or singleInstance launch mode in the manifest. If you think about it, that also makes sense. The developer of the app has specified in the manifest that he expects a singleTask or singleInstance Activity to be at the root of a task. If you (as another app's developer) could override this behaviour by simply launching the Activity with some other flags, this would break the expected behaviour of the original developer's app.

Again, singleInstance and singleTask launch modes are used for very specific and special purposes and are not generally necessary. They have very specific and somewhat unexpected behaviour, which unfortunately confuses a lot of developers.

The documentation of these behaviours is often incorrect, incomplete or confusing. Sigh... Welcome to mobile development!