The android documentation defines single task launch mode as :-
The system creates a new task and instantiates the activity at the
root of the new task. However, if an instance of the activity already
exists in a separate task, the system routes the intent to the
existing instance through a call to its onNewIntent() method, rather
than creating a new instance. Only one instance of the activity can
exist at a time
Now my question is what happens in the case where the instance of activity already exists in a separate task but it is not at the top of the task. Are all activities above this activity destroyed and the new intent is delivered to this activity ? (as in FLAG_ACTIVITY_CLEAR_TOP with FLAG_ACTIVITY_NEW_TASK)
Yes, it will. You can test it by making a simple test app. New intent will be received in onNewIntent()
Related
This is an image from android documentation:
Activity Y has 'singleTask' launch mode but it is not root activity in the task, that is Activity X. How did it happen?
Upd.:
From the documentation:
"singleTask"
The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.
Note: Although the activity starts in a new task, the Back button still returns the user to the previous activity.
Single task only means that this activity can only be created once cf to this website: http://inthecheesefactory.com/blog/understand-android-activity-launchmode/en
It doesn't matter if the activity is root or not.
singleTask:
This mode is quite different from standard and singleTop. An Activity
with singleTask launchMode is allowed to have only one instance in the
system (a.k.a. Singleton). If there is an existed Activity instance in
the system, the whole Task hold the instance would be moved to top
while Intent would be delivered through onNewIntent() method.
Otherwise, new Activity would be created and placed in the proper
Task.
I think the answer is that this activity was launched with an intent with FLAG_ACTIVITY_SINGLE_TOP flag, because intents have higher priority than xml tags.
I want to start an activity from service context. But I am bound to use flag = Intent.FLAG_ACTIVITY_NEW_TASK which is creating multiple instance of the activity since it is throwing Run-Time-Exception with other flags.
How can we launch an activity from service so that multi instances of activity will not be created, if already activity in recent tasks it will launch that only??
You can combine different flags, like FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
...
This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.
and FLAG_ACTIVITY_CLEAR_TASK
If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.
with FLAG_ACTIVITY_NEW_TASK. Which one to use depends on what exactly do you want to achieve.
Check the documentation of the flags in the Intent class and Tasks and Back Stack.
I have an app that is very hierarchical (activities are similar to League > Team > Position > Player) and so I've made each activity singleTop in order to keep navigation sensible and to prevent duplicate instances.
Now I'm making my second app and I've seen it suggested to declare my application to be singleTask to prevent duplicate instances. Could someone help explain the advantages of each approach?
My new app is just an activity with 3 fragments and then I'll probably add a settings activity and maybe a FAQ.
EDIT: I just realized that singleTask is NOT preventing duplicate instances of my app, as I had thought. Now looking for the right way to handle this...
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 activity launchMode
4 modes...
"standard"
"singleTop"
"singleTask"
"singleInstance"
The default mode is "standard".
The modes fall into two groups. standard and singleTop comes in one side and singleTask and singleInstance comes in another side.
The main difference between standard and singleTop is in standard, every time a new intent for standard activity, a new instance is created. In case of singleTop too, a new instance is created but an instance of the activity is already in top of the stack, it wont create a new instance.
Actually, the issue comes , when we download an application from a server and launch it and open it from there itself. After launching the application, press home button. Then click the all programs and select the icon of the application from home screen. Then another activity will be created in the case of standard, but in singleTop , no new instance will be created.
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 at the root of the activity stack, but other activities (necessarily "standard" and "singleTop" activities) can be launched into the same 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.
http://smartandroidians.blogspot.in/2010/04/activity-launch-mode-in-android.html
I found the answer here:
http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode
"singleTop":
The difference from 'standard' is, if an instance of activity already exists at the top of the current task and system routes intent to this activity, no new instance will be created because it will fire off an onNewIntent() method instead of creating a new object. Let's take the Twitter-oauth integration as example.
"singleTask":
A new task will always be created and a new instance will be pushed to the task as the root one. However, if any activity instance exists in any tasks, the system routes the intent to that activity instance through the onNewIntent() method call. In this mode, activity instances can be pushed to the same task. And if the user clicks the BACK key from the singleTask activity, the system will return the user to the previous activity.
From Understanding Activity launch mode:
standard (default) :- Multiple instances of the activity class can be
instantiated and multiple instances can be added to the same task or
different tasks. This is the common mode for most of the activities.
singleTop :- The difference from standard is, if an instance of the
activity already exists at the top of the current task and the system
routes the intent to this activity, no new instance will be created
because it will fire off an onNewIntent() method instead of creating a
new object.
singleTask:- A new task will always be created and a new instance will
be pushed to the task as the root. However, if any activity instance
exists in any tasks, the system routes the intent to that activity
instance through the onNewIntent() method call. In this mode, activity
instances can be pushed to the same task. This mode is useful for
activities that act as the entry points.
singleInstance:- Same as singleTask, except that the no activities
instance can be pushed into the same task of the singleInstance’s.
Accordingly, the activity with launch mode is always in a single
activity instance task. This is a very specialized mode and should
only be used in applications that are implemented entirely as one
activity.
As I read in several stackoverflow answeres. To start activity from the service you have to use FLAG_ACTIVITY_NEW_TASK, but it will create new instance of activity in separate task. I want to reuse already started activity. Im trying to do it from IntentService that listen for c2dm notifications.
In the manifest for the Activity, you could set android:launchMode="singleInstance".
Here's what the docs say about singleInstance:
Only allow one instance of this activity to ever be running. This
activity gets a unique task with only itself running in it; if it is
ever launched again with the same Intent, then that task will be
brought forward and its Activity.onNewIntent() method called. If this
activity tries to start a new activity, that new activity will be
launched in a separate task. See the Tasks and Back Stack document for
more details about tasks.
And here is where I got my info.
You must use this flag with your Intent:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
IF you don't want a new instance of your Activity, set launchMode for your Activity in the AndroidManifest file:
android:launchMode="singleTask"
I have created an activity. I made the launch mode as singleTask in manifest file. I donot want multiple instance of the same activity should start. I am lunching this activity on button click of another activity.
If i click the button more than once then as i have made the activity as single task then If the activity already running then nothing happens. But I want to relaunch the activity without creating another instance. How to achieve this.
Thanks
Deepak
But I want to relaunch the activity without creating another instance
What you meant my relaunch without creating. I think you may have set of code that you have placed in your onCreate and you want to run when the activity again got control. If so its better for you to place that code to your onResume or onNewIntent. Because onCreate of the single task will only execute once
singleTask
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.