Example: I have an android app with 3 activities that has the following behaviors:
A (Home) -> B -> C
Activity A launches Activity B
Activity B launches Activity C
When user is on Activity B and they hit the Back button, it takes them Activity A
When user is on Activity C and they hit the Back button, it takes them Activity B
What I would like is when user is on Activity C, if they hit the "My Root Activity" button, it will take them to Activity A without adding a new instance of Activity A to the back stack.
So I don't want to have:
1) A
2) A-B
3) A-B-C
4) A-B-C-A
What I would like is:
1) A
2) A-B
3) A-B-C
4) A
How can I do this?
Check out the intent stack machinery!
http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
EDIT:
You can add "singleTaks" or "singleInstance" to your activity in the manifest file and implement the onNewIntent() method.
"singleTaks"
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.
"singleInstance"
Same as "singleTask", except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task.
Check out this link
I have each child activity extend a base activity. In the base activity, I defined an onActivityResult() which will impose a finish() if the activity at the top of the stack set a specific resultCode. So if they hit the "My Root Activity" button on Activity C, it will recursively roll up to Activity A. The Back button maintains it's functionality.
This is a rare scenario as I would have used "singleTask" but launching Activity A involves reloading it's dependencies which I don't want to couple of Activity C.
Related
I have activities A and B. Activity B is started by a service while the application is closed and activity A is not on the stack. Activity A has members that B requires access to. I would also like the home button to open activity A from Activity B even if activity B is started from a service. Is there a way to inject activity A back into the stack?
In your Service start ActivityA not ActivityB and pass some parameter to ActivityA.. and in ActivityA's OnCraete method launch the ActivityB.. now you have both in the stack.
You can declare the logical parent of each activity in your manifest file, using the android:parentActivityName attribute (and corresponding element),for home button working.
And to add a activity back to stack
Check this link for more details.
That won't be a good decision, better use the members in the B Activity and Once Activity B is launched and it's about to leave just give intent to Activity A.
Also you can check if Activity A is already in the stack. If already in the stack, it will popup by itself, if not found, can pro grammatically trigger it.
I would like to ask similar question to:
Go back to previous screen without creating new instance
However I don't want Activity A go through onCreate callback, I would like to return to previous instance in the same state. How to achieve that without calling multiple finish() ?
There's no need to finish() activities as you navigate through your application. Instead, you can maintain your Activity back-stack and still achieve your goal. Let's say you have 4 activites like so:
A --> B --> C -->D
where D is the topmost activity and A is root activity. If you are 'falling back' to activity B, then you'll need to do two things in order to avoid hitting B's onCreate method.
1.) Make B a "SingleTask" activity. You can do this in the Android Manifest. To be brief, this means that only one 'instance' of B will ever exist within this Task. If B is already running when it's called then it will simply be brought to the front. This is how you do that.
<activity
android:name=".ui.MyActivity"
android:launchMode="singleTask"/>
But you don't want to just bring B to the front. You want to 'fall back' to B so that your stack looks like
A--> B
2.) Add this flag to your intent that 'starts' B. This ensures that C and D are removed.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Now when 'D' calls new Intent to B, B will be resumed and C and D will be removed. B will not be recreated, it will only call onNewIntent.
When navigating from A to B do not finish Activity A.
When navigating from B to C finish Activity B.
When navigating from C to D finish Activity C.
So from wherever you navigate back finish current Activity and Activity A will get resume again not get created.
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
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!
Here's what I want to do:
If I use startActivity I start a new Activity and I can't use StartActivityForResult from Main Menu -> Total. I would like to go back on the Main Menu activity already present in my stack and remove Activities A, B ,C and Total.
Have you tried using FLAG_ACTIVITY_CLEAR_TOP flag in your intent (used to start "Main Menu" from "Total")?
http://developer.android.com/reference/android/content/Intent.html#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.
To remove activities A,B,C, and Total from your stack, just call finish() on these 4 activites.
See also : Tasks & Back stacks and Activity task Design