SingleInstance of Android launchMode
This one is pretty easy: taskAffinity
trumps launchMode
. This means, if you launch an Activity
and that Activity
has the same taskAffinity
as other activities within a task, the special launchMode
s singleTask
and singleInstance
are ignored.
So unfortunately, the documentation isn't 100% correct, because there are some situations where singleInstance
and singleTask
launch modes do NOT behave the way they are documented.
In general, you should not be using the special launch modes singleTask
or singleInstance
as these come with a lot of side-effects that are not obvious. You shouldn't need these special launch modes unless you are implementing a HOME-screen replacement.
Android singleTask or singleInstance launch mode?
From the Application Fundamentals page of the Android dev guide:
By default, all the activities in an
application have an affinity for each
other — that is, there's a preference
for them all to belong to the same
task.A "singleInstance" activity stands
alone as the only activity in its
task. If it starts another activity,
that activity will be launched into a
different task regardless of its
launch mode — as if
FLAG_ACTIVITY_NEW_TASK was in the
intent. In all other respects, the
"singleInstance" mode is identical to
"singleTask".As noted above, there's never more
than one instance of a "singleTask" or
"singleInstance" activity, so that
instance is expected to handle all new
intents. A "singleInstance" activity
is always at the top of the stack
(since it is the only activity in the
task), so it is always in position to
handle the intent. However, a
"singleTask" activity may or may not
have other activities above it in the
stack. If it does, it is not in
position to handle the intent, and the
intent is dropped. (Even though the
intent is dropped, its arrival would
have caused the task to come to the
foreground, where it would remain.)
Since there is never more than one instance of the Activity with either launch mode, the back button will always take you to the existing instance of the Activity in your case.
An important difference is that "singleTask" doesn't require the creation of a new task for the new Activities being launched when something is selected. Nor will it have to remove that new task on the back button each time.
Since your Activity stack does all pertain to one user "task", and it doesn't sound like you have an intricate Intent structure where singleInstance may be beneficial to always handle them, I would suggest using the singleTask launch mode.
Here is a good blog post for more info, as well as credited for the image: Android Activities and Tasks series – An introduction to Android’s UI component model
Setting launchMode= singleTask vs setting activity launchMode= singleTop
I think your definition of singleTop and singleTask is a little off. SingleTop could produce a duplicate instance. Lets use your example, League > Team > Position > Player. If there is a button in the player screen that will take you to the league screen, it will become League > Team > Position > Player > League.
Whereas singleTask guarantees that only one instance of the activity can exist.
android - Two activities with launch modes as 'singleInstance'
I'll bold the answer to your question if you don't want to read the clarification.
When using launchMode="singleInstance"
, there's two things to keep in mind:
- The Activity will always be created in a new task
- All Activities launched from this Activity will be created in a separate task
As such, an Activity with launchMode of singleInstance
will always be isolated in it's own task. There won't be another Activity inside of that task.
So with your example from your question of Activities A, B, C, and D:
- Activity A launches Activity B
- Activity B is
launchMode="singleInstance"
so it's on a new task - Activity B launches Activity C
- Activity C is launched in the same task as Activity A
- Activity C launches Activity D
- Activity D is
launchMode="singleInstance"
so it's on a new task
From what happened here, you have one a task that stores the launchMode="standard"
Activity A and Activity C. Activity B is in it's own task. Activity D is in it's own task.
Therefore, if you choose to Back out of these Activities, you'll notice that:
- Activity D is backed and Activity C appears
- Activity C is backed and Activity A appears
This happens because Activity C is on the same task as Activity A.
Also, Activity D definitely won't be in the same task as Activity B because Activity B's task is meant only for Activity B due to launchMode="singleInstance"
.
Keep in mind that there can be any number of tasks being held in the background at once. Just that if there's too many being held or if the system requires memory, it'll start destroying these background Activities across your multiple tasks.
Understanding Android Launch modes with splash screens
There are a number of things going on here, I'll try to address these:
First off, using launchMode="singleInstance"
is problematic here, because you have not declared any taskAffinity
for any of your activities. So your SplashActivity
and your other activities have the same (default) taskAffinity
which tells Android that all these activities want to run in the same task, which conflicts with your launch mode declaration of SplashActivity
. This is bad, and you shouldn't do it. If you really want to have activities running in separate tasks, you should ensure that they have different taskAffinity
so as not to cause confusion.
Secondly, you wrote:
This seems to work, but there is something that I don't understand.
Why is the second Splash ignoring the Intent to launch Login
activity?. The logic tells me that a Login #2 should've launched.
What is happening here is this: When SplashActivity
calls startActivity()
to launch LoginActivity
, the Intent
used contains FLAG_ACTIVITY_NEW_TASK
set (because SplashActivity
is declared with launchMode="singleInstance"
so it has to launch other activities into a new task), so Android looks for an existing task that has LoginActivity
as its root Activity
. If it didn't find one, it would simply launch a new instance of LoginActivity
into a new task. However, in this case, it finds one (this is task #2 in your diagram), so instead, it just brings that task to the foreground without launching a new instance of LoginActivity
.
This is the same behaviour as what happens when you have an app running, then press the HOME button and then click the app icon for that app again. Android doesn't launch a new instance of the app's root Activity
in this case, it simply looks for an existing task that has the app's launch Activity
as its root Activity
and brings that task to the foreground in whatever state it was in.
My suggestion for you is as follows:
- Get rid of the use of the special launch modes
singleInstance
andsingleTask
- Create a new
BridgeActivity
which is used as a bridge between the web browser and your app. ThisActivity
should have the<intent-filter>
for the browserIntent
. - The
BridgeActivity
should check if it is the rootActivity
in its task. If it is not, it means that it has been launched into an existing task that was brought to the foreground and it can just quietlyfinish()
inonCreate()
. - If
BridgeActivity
detects that it is the root of its task, it can launchSplashActivity
(make sure to setFLAG_ACTIVITY_NEW_TASK
) to begin a new task (since there obviously wasn't already an existing task of your app) BridgeActivity
should be declared so that it doesn't end up in the task stack history or in the list of recent tasks (noHistory="true"
andexcludeFromRecents="true"
)
Difference between singleTask and singleInstance
What is unclear from the docs ?
The "singleTask" and "singleInstance" modes also differ from each
other in only one respect: A "singleTask" activity allows other
activities to be part of its task. It's always at the root of its
task, but other activities (necessarily "standard" and "singleTop"
activities) can be launched into that task. A "singleInstance"
activity, on the other hand, permits no other activities to be part of
its task. It's the only activity in the task. If it starts another
activity, that activity is assigned to a different task — as if
FLAG_ACTIVITY_NEW_TASK was in the intent.
singleTask launch mode is not working
So it seems the issue is with device. On emulator and other devices with same android version singleTask works just fine.
Related Topics
How to Monitor the Network Connection Status in Android
Viewpager with Previous and Next Page Boundaries
How to Launch Activity Only Once When App Is Opened for First Time
How to Extract a List of Objects from Firebase Datasnapshot on Android
How to Set Tint for an Image View Programmatically in Android
Draw Multi-Line Text to Canvas
Android Heap Size on Different Phones/Devices and Os Versions
Record/Save Audio from Voice Recognition Intent
How to Enable Google Play App Signing
Open Link of Google Play Store in Mobile Version Android
Media Player Called in State 0, Error (-38,0)
How to Escape Special Characters Like ' in SQLite in Android
How to Build the Android Sdk with Hidden and Internal APIs Available
How Set Spannable Object Font with Custom Font
How to Use the Simple Http Client in Android