Search code examples
androidandroid-intentlaunchmodesingletask

When marking main activity as `singleTask`, it will destroy other activities when launched from the launcher


When marking the main activity as singleTask, it will destroy other activities when launched from the Launcher. But when launched from Recents, it will just resume the latest opened activity. Why does it work like that? And how can I prevent it.

So to illustrate, (Activity A is marked as singleTask), the behaviour is as follows:

Activity A -> Activity B -> Open app from Launcher -> Activity A

Activity A -> Activity B -> Open app from Recents -> Activity A -> Activity B

I would expect the same stack (A -> B) when opening from the Launcher.

I read a lot of StackOverflow and Reddit posts, but none of them seem to fully apply to my situation and/or correctly explain why it's happening and how to solve it.

This post for example, seems to describe my exact problem. However I don't know how the mentioned solution should work. Because in my reproduction onCreate is never called. Moreover Activity B is destroyed. So even when I would be able to call finish in the onCreate method in Activity A, I would end up finishing the whole app instead of only that instance of Activity A

Reproduction on GitHub: https://github.com/tafelnl/android-single-task-launch-reproduction It's just a simple app with two activities. The MainActivity is marked as singleTask and launches SecondActivity by means of an intent. You can observe that the behaviour is as mentioned above.


Solution

  • Do not use singleTask launchMode on your MainActivity (ACTION_MAIN & CATEGORY_LAUNCHER) in case of other Activities (e.g. SecondActivity) being destroyed by Android in the same taskAffinity when user tap on the Launcher to bring your app to foreground.

    Alternatively, safely, if you do certainly need to do that on purpose to maintain a singleton Activity, you could create a SplashActivity as entry without any UI for good regardless of other diverse launchMode set on later Activities:

    <!-- AndroidManifest -->
    <activity
        android:name=".SplashActivity"
        android:launchMode="standard">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
    <activity
        android:name=".MainActivity"
        android:launchMode="singleTask">
    </activity>
    

    // SplashActivity
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startActivity(Intent(this, MainActivity::class.java))
        finish()
    }