I have Activity A, B and C
C is launched from notification.
But, backstack gets cleared when launched from notifications. I know about TaskStackBuilder and specifying the back intents, but that will be a hardcoded back stack.
If C is launched after A, then back press should go back to A
If C is launched after A>B, then back press should go back to B and then got back to A on second back press.
How do I preserve the current back stack and add on top of it?
Set all the possible target activities' launchMode in your Manifest.xml to either "singleTop" or "singleTask" depending of your need:
<activity
android:name=".YourActivity"
android:launchMode="singleTop">
The different launch modes are well explained here.
Related
See I have 3 activities, A, B and C. I go to activity C from A.
A -> B -> C
While in activity C, press home button and leave it for some long time. When I bring application back to foreground after some long inactivity either from application back stack or from launcher icon, I land on activity C. Now, while in activity C, if I press back button or click back navigation arrow from action bar, application restarts and starts activity A instead of resuming activity B.
What could possibly cause this behaviour?
Check whether you doing like this or not
<activity
android:name=".C"
android:parentActivityName=".B">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".B" />
</activity>
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.
Activity A is the main launcher Activity for my app
A starts Activity B upon some condition
Activity C is the Settings Activity
Android Manifest- C is the parent of B, as shown below:
<activity
android:name=".view.ActivityB"
android:label="#string/title_activity_favorite"
android:parentActivityName=".view.ActivityC">
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".view.ActivityC" />
</activity>
Flow:
I start the app, Activity A is called
A starts B
When I click on
back button in the Status Bar, I am routed to A not C. Any clue why
is this is happening
You have a problem understanding how activities are started and finished. Having your example, if activity A starts the activity B it doesn't mean that the system is creating the activity C (simply because is the parent of B) to insert it between A and B, and this is why when back is pressed the activity A is resumed. To add an activity C between A and B without explicitly creating it read this post about creating a proper back navigation. If you have any problems reply with a comment.
Here is the confusion:
The android Back Button is calling (popping) the top of Back Stack so if not manually manipulated, it contains the last called activity. In your case Activity A is called just before Activity B so the top of the Back Stack is Activity A
But there is another soft back button in the android as displayed in the following image:
it is usually displayed in the top left corner of the screen. The behavior of this button is what is described in your Manifest. So if you are in Activity B and you press this button you will go to Activity C instead of Activity A
You can manually change the behavior of the Back Button with TaskStackBuilder
And again about Android activities back stack magic. So I have two activities A→B (playlist A and player B), and I want the app should always close when Back pressed in A. But it doesn't.
Both activities launches as singleTop, B also has android:excludeFromRecents="true" and defined A as parent. B goes back to A with following flags Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK.
Everything works fine except the next case:
A→B,
Home pressed,
Launch app again from desk and got A opened,
Press Back button,
Here app should be closed but B shown again.
Any suggestions? Thanks!
When you are using the Intent.FLAG_ACTIVITY_NEW_TASK , it means a new instance of the activity is launched. You may have to use Intent.FLAG_ACTIVITY_SINGLE_TOP flag with single task option in manifest.
How do these two attributes relate? If I have android:noHistory="true", does having android:finishOnTaskLaunch="true" have any significance/meaning?
Let's say you have three activities in your app: A, B, and C.
You start your app and see A, click a button and see B, click a button and see C.
First scenario
Now if you press the Back button on your phone, you will see B.
Second scenario
Let's say that B has android:noHistory="true".
Now if you press the Back button on your phone, you will see A. The android:noHistory="true" attribute removed B from the history (i.e. the activity stack), so you will not see it when you hit the Back button.
Third scenario
Let's say that C has android:finishOnTaskLaunch="true".
Now if you press the Home button on your phone and then launch the app again, you will see B. Android ended C when you launched the app again because it has the android:finishOnTaskLaunch="true" attribute.
finishOnTaskLaunch would kill the Activity as you move to another task. But noHistory would kill the Activity if you move to another activity in the same task.