I'm new to Android development and here's my problem:
I have 2 activities: A and B.
From A, I call B via startActivity(new Intent(A.this, B.class))
From B, I do some things and return to A the same way: startActivity(new Intent(B.this, A.class))
However, when on new-A I press "Back" button, first I see B class and then the old (unchanged version) of A class.
I've tried placing finish(); inside onPause() method. However, then my Activity crashes on orientation change.
How can I properly control activity backstack? Thanks in advance.
When you call startActivity without any additional flags, you will create a new instance of the Activity specified. This means that your back stack ends up looking like this:
A -> B -> A(2)
You have two options:
First option, you can add flags on the Intent that instructs it to reorder A to the front if it is already present in the back stack. Note that this will not close B; you have to call finish() in B afterward.
Intent intent = new Intent(B.this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startAcvitiy(intent);
finish();
Second option is to use startActivityForResult instead of startActivity in A and have Activity B pass a result back to A. I think this is much cleaner and it gives you a very easy way to react to what happened when B was finished (e.g. you can update your UI). See this guide from the Android developers site.
Either StartActivityForResult or think about using fragments. If you need to jump between activities think about why you are doing this? If you are passing info between the two then there are a couple of options. Fragments give you the option and you can hold the data on the Activity that hosts the fragments or you can have a Singleton living in an Application class that you would extend.
Read about activity lifecycle - here. You have to implement saving of instance.
It sounds like that rather than calling startActivity in to go back to A, you can just call instead finish();. This will land you back on your previous Activity.
Alternatively you can accomplish the same if you use FLAG_ACTIVITY_CLEAR_TOP:
Intent intent = new Intent(B.this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Regarding the accepted answer's suggestion to use FLAG_ACTIVITY_REORDER_TO_FRONT - for your case it really doesn't matter. but in a slightly different case where you have A->B->C and you use REORDER to go back to A, you'd actually end up with a stack that looks like B->C->A. With CLEAR_TOP, you'd end up with just A. Point is, REORDER is meant to REORDER, CLEAR_TOP is supposed to pop the backstack. In your simple case they happen to accomplish the same, but in my opinion it's better practice to use the flags as they're intended.
Related
I have two activities, A and B.
1) From activity A you can go to B and return to A via back button (resume).
2) From activity A you can go to B, make a selection, which will return to activity A via reloading it. Here I need to clear out the previous copy of activity A from the back stack.
In the second case I am using the following intent:
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
This works, but my new activity is drawn first, then I can see the old copy getting removed - so there's some animation of the same activity going away. Is there any way to either reverse that behaviour so that the old activity is removed first, or alternatively get rid of that animation? Thanks!
EDIT:
In terms of a workaround, for now I'm setting activity A as a singleTask in manifest, overriding onNewIntent and resetting all my objects that I need to reload in onResume. That seems to be working but I'd prefer a clean slate, i.e. reload the activity
Currently I have 3 Activity classes A, B and C.
Activity A is a singleTask while other has the default launch mode.
Consider a case: the user is first in A, then starts B, and then starts C.
The back stack now is ABC.
Next, the user starts A again.
The back stack now is A, but what I would like to be achieved is ABCA.
I know not setting Activity A to be singleTask can have a back stack : ABCA.
But I really need the Activity A to be the same instance.
Anyone know how to do this?
You have stipulated two conditions:
what I would like to be achieved is ABCA.
and
I really need the Activity A to be the same instance.
These two conditions are mutually contradictory. Absolutely.
What you want is impossible.
That is all.
Are you sure you need singleTask and not singleTop ? Could you describe why do you need it singleTask ?
That is not possible.
if you want to open existing activity then
launch your activity as
Intent intent = new Intent(this, YourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
hi i have an application
A is launcher activity from that i create B activity. From B i want to go back to A without deleting the instance of B(so no finish) then i want to create a new instance of B lets call it B2. And from A i want to be able to show B or B2 without recreating them.
again i stress that B,B2 are the same class just diffrent instances.
from B when i want to go to A i thought of using
Intent myIntent = new Intent(getBaseContext(), MainAct.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(myIntent);
but i think that its a mistake because it will clear other instances.
what intent must i use in the cases?
in c# windows application we would do B.hide();A.show(). then from A we could do
A.hide(); B.SHOW() or B1.show();
how can i do that in android please?
If B is an Activity, you can't have two different instances of it.
You can have 2 different Activities that extend the same class, but you've indicated you don't want that.
You need to find a way to change the appearance and behavior of B rather than creating a new instance.
Please consider reading about the Activity Lifecycle.
use FLAG_ACTIVITY_REORDER_TO_FRONT
from the doc
If set in an Intent passed to Context.startActivity(), this flag will
cause the launched activity to be brought to the front of its task's
history stack if it is already running.
Is there a possibility to reopen a specific activity from the stack?
So say I open activity a, then b, then c. I do not finish a and b while starting new activities. If a push my back-button without overriding it, I would go to B now of course.
But I want to give a button or maybe the back button to open A, or B independent from its location in the stack. This is kind of achievable by finishing the activities (if I would finish b, and press back button from C, I would go to A). But some of my activities I'd rather not finish.
I researched but could not find how to achieve this. Is this possible?
Of course there would be a check needed if the activity is active, and if it is then reopen it or else open it.
You will obviously have to figure out what logic you want to know which Activity to open but this should achieve what you are looking for
#Override
public void onBackPressed()
{
super.onBackPressed();
Intent intent = new Intent(CurrentActivity.this, ActivityYouWant.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
Let me know if this isn't what you were looking for.
Flag
the way codeMagic suggested you may produce more Activities in the Activity stack then you need. This may leed to Memory Leaks or other bad behavior.
you should take a look at:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
or even better finish() your Activities.
I am having trouble popping all activities off the stack using Intent.FLAG_ACTIVITY_CLEAR_TOP and android:launchMode="singleInstance".
In my application activity A, launches activity B (via startActivity) which in turn launches activity C (via startActivity). On activity C the user presses a menu item to return to activity A. When they arrive at activity A, I want only A on the stack such that if they click the back button they return to the home screen (desktop).
This is the code that I am currently using when the user presses a button to return to A:
Intent i = new Intent(this, A.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
All activities are defined as android:launchMode="singleInstance" in the project manifest.
My code doesn't seem to work though. Once I'm back on activity A if I click the back button I return to activity C. Am I misunderstanding how to use Intent.FLAG_ACTIVITY_CLEAR_TOP?
I've always found the best way to ensure C would be removed from the stack is to call finish() after startActivity to remove C from the stack.
The documentation does read as though things would behave the way you expected them to, but it would seem this isn't happening, so finish() will ensure C is removed.
I usually use the technique Al suggested (calling finish() after starting the new activity).
You could also experiment with task affinity. I've never done that myself, but it may be relevant in your case as well. See this thread: http://groups.google.com/group/android-developers/browse_frm/thread/ca3b26a14d024597/129e37375105901b