Launch existing singleTask Activity from launcher icon - android

Scenario:
Activity A (MAIN and LAUNCHER in manifest) starts up when clicking on launcher icon.
In turn it launches Activity B.
Activity B then launches our main app Activity C (MAIN and singleTask in manifest).
Behaviour I require:
Once Activity C has been shown and the home key is then pressed, the next time the launcher icon is pressed I would like to skip straight to Activity C (and not show Activity A (and consequently B) again).
I have tried using FLAG_ACTIVITY_CLEAR_TOP from A, but I still get Activity A whenever I hit icon on launch screen.
Is appearance of my singletask Activity C from launcher achievable?
Update: Use of FLAG_ACTIVITY_CLEAR_TOP from A and not calling finish() creates the situation whereby Activity B appears on press of launcher icon. However, also applying use of FLAG_ACTIVITY_CLEAR_TOP from B and not calling finish() does not resolve situation. now I don't get A on launcher icon press, but get B. What gives!

See similar scenario here.
In your case, I would recommend using a similar approach, where you would have a SharedPreference that would persist a value representing whether your app had previously been launched.
Create a simple Activity that will contain the logic for what you are trying to do here. In that activity's ("pre-A" Activity) onResume() method, check the value of the preference representing whether the app has ran previously.
If it has not previously been ran, launch an intent to Activity A, which calls the subsequent B and C activities; otherwise, launch an intent to Activity C.
Seems pretty straightforward, just remember to define the new "Pre-A" activity in your manifest!

Related

How to resume activity when application relaunched from android launcher?

I have an application that implements two activities. Activity A is for selecting some files on device and activity B is to show additional info while these files are processing. Both of them have singleInstance as launch mode.
On application's start activity A runs. Then this activity starts second activity B, that creates a notification. If I tap this notification or open running app from recents, it works fine and shows running activity B. But if I'd started application before and activity B is already running, launching it again from app menu causes showing activity A when old activity B is already running and accesible from notification bar.
So, what should I do to make application run only single activity at the same time and show second activity when called from launcher (if second activity once started and isn't finished)?
Your launcher intent should be mapped to a dummy activity, with no view (or may be a splash who knows !). In onCreate of that dummy activity you check if a state was saved previously and based on the state switch to the desired activity.
And how to set the state ? well lets try something simple. lets say when Activity A resumes we put "A" to some key in SharedPreference. if Activity B resumes we put "B" to the same key in preferences. Now your application goes out when Activity B was visible, the state saved would be "B", you launch from home screen, the dummy activity finds "B" in the state and launch intent to go to B else go to A.

How start another package ontop of the stack?

I have to app stacks like this:
A->B-C->D
X->Y
In Y I want to use getLaunchIntentForPackage("package") to get to D, however I get to
A. What launch mode should I use etc? I would like to use singleTask for ABCD if possible.
Also when in D and I press home and launch via the Icon for A again then depending on launch mode I don't get to D (that I would like), but to A. DCB are cleared.
I tried a lot of things but I just don't understand how it works. I don't seem to get a consequent behaviour.
getLaunchIntentForPackage just gives you the Main activity of package. In your first app i am guessing it is A. So if you try starting it from 2nd app (X->Y), it will start A and not D which is a different activity. So you are not getting to D.
When you press home and click launch icon for first app, if there is already a task for it, it is brought foreground. Looks like A, the app's main activity (A) gets invoked - not the stack top activity D. And B->C-D get cleared because you may be using singleTask launch mode for Activity A, which tries to take you back to activity in existing task.
So what you observe is expected. The launch modes are defined per activity, not per app/package level.
So to get from Y to D, you need to start activity D using intent flag set to FLAG_ACTIVITY_NEW_TASK, this will ensure you get to the existing D, that is already on top in your first task (A->B->C->D)
To do the same from home screen (launcher icon) you may need to try below options for SingleTask mode, since you want to preserve the existing stack (A->B->C-D) , and simply want get to D; Quoting from the link:
"+ For launchMode=singleTask if there is an intent_filter in the
manifest the task stack is always cleared after returning to Home and
re-launching (returns to main activity instead of last activity).
+ For launchMode=standard re-launch from Home instead returns to last
activity in task (as expected).
+ If there is no intent_filter listed then even with
launchMode=singleTask re-launch from Home returns to the last activity
in the task"
So, set your main activity launch mode to standard, it will let you preserve the stack as-is (2nd +point above). You can still start this in singleTask mode using intent-flags (eg: FLAG_ACTIVITY_NEW_TASK) from your other app. Intent flags override manifest launch modes, see here

ANDROID: Activity state after pressing the back button

Imagine you have the following sequence of activities:
Activity A -> Activity B -> Activity C
When you are on Activity C, pressing the native back button, takes you to Activity B. Now what is the state of Activity C? Is it still in memory or it has been finished?
If it is still in the memory, is there a way to resume the activity? Other than starting another instance of this activity...
I should add that this is the standard case where you do not use any flags including: FLAG_ACTIVITY_CLEAR_TOP
Default behavior is that when you press hardware "back" button, current activity will be removed from the backstack and activity "destroy" sequence will be initiated. From that moment you should not rely on the fact that it might be somewhere around - it is all up to Android to decide when does it actually kill this activity.
What my previous investigations show is that victim's onDestroy() will be called only when new activity is done loading and is idle.
You can specify android:launchMode="singleInstance" for your activity in Manifest. This will ensure that only one instance of activity is created at the time
You might want to consider reading the official docs.
More specifically the part that answers your question:
When the user presses the Back button, the current activity is popped from the top of the stack (the activity is destroyed) and the previous activity resumes (the previous state of its UI is restored).
Now for your second question… you can keep reading the same page…
when you start an activity, you want to bring forward an existing instance of it (instead of creating a new instance on top of the back stack)
So if you read that… you will find…
You can do these things and more, with attributes in the
manifest element and with flags in the intent that you pass to
startActivity().
In this regard, the principal attributes you can use are:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
And the principal intent flags you can use are:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
No, it is not in memory. It gets finished when you press the back button. You should use android:launchMode="singleTask" in the androidmanifest.xml for that particular activity for which you want no new instances to be created if an instance is already there. For further information this link will be helpful.
In the following sequence...
Activity A -> Activity B -> Activity C
When you will press back button in Activity C then onBackPressed() method will be called. The default behavior of onBackPressed() is to finish the current activity until you Override the functionality.
So, in normal case, after back press the current Activity will be destroyed and you can't find it in the Activity Stack, so you can't resume it.
You will find more information from Android Developer's doc in below link...
Tasks and Back Stack

Android: How to make launcher always open the main activity instead of child activity? (or otherwise)

I have activities A and B. The A is the one with LAUNCHER intent-filter (i.e. the activity that is started when we click the app icon on home screen).
A launches B using startActivity(new Intent(A.this, B.class)).
When the user has the B activity open, and then put my application into the background, and later my application's process is killed, when the user starts my application again, B is opened instead of A.
This caused a force close in my app, because A is the activity that initializes the resources my app needs, and when B tried to access the uninitialized resources, B crashes.
Do you have any suggestions what should I do in this situation?
Well you should really have activity B initialize your resources too. But you can put android:clearTaskOnLaunch="true" in your manifest for activity A to have the launcher always go to that activity.
Have you tried setting Flag FLAG_ACTIVITY_NEW_TASK while creating intent.
In your case please try startActivity(new Intent(A.this, B.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))

Closing several android activities simultaneously

In my application you can navigate through several Activities until the Activity stack is quite deep.
We'd like a button on every Activity that will take you straight back to the main menu - i.e. pop all Activities from the stack except the first one.
I've put the button in a View that I can easily put on every Activity in the application, but I can't figure out how to close several Activities in one fell swoop.
(If possible, it would be good if the View could work out how many Activities to close by itself - i.e. detect how deep on the stack its own Activity is.)
Have a look at the intent flag FLAG_ACTIVITY_CLEAR_TOP which says it brings the targeted activity to the top of the stack, removing everything else that might have been above it. So use that button you can add to all your activities to launch an intent which targets your main menu, with that flag set.
From the documentation:
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.
For example, consider a task
consisting of the activities: A, B, C,
D. If D calls startActivity() with an
Intent that resolves to the component
of activity B, then C and D will be
finished and B receive the given
Intent, resulting in the stack now
being: A, B.
The currently running instance of
activity B in the above example will
either receive the new intent you are
starting here in its onNewIntent()
method, or be itself finished and
restarted with the new intent. If it
has declared its launch mode to be
"multiple" (the default) and you have
not set FLAG_ACTIVITY_SINGLE_TOP in
the same intent, then it will be
finished and re-created; for all other
launch modes or if
FLAG_ACTIVITY_SINGLE_TOP is set then
this Intent will be delivered to the
current instance's onNewIntent().
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.
You could declare that first activity android:launchMode="singleTask" (more) and then just start it with an Intent.
EDIT: My suggestion is based on the assumption that you want to have a single instance of the Activity to return to. Otherwise it's incorrect.

Categories

Resources