For example, I opened activities A, B, C, D.
I want to finish D and C and return back to B.
I don't want to open activity B with clear tasks and new task flags. I want to keep activity A too so user can return from B to A with back button.
How can I achieve this?
Intent intent = new Intent(getApplicationContext(), B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
And in B activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
I think you can add this.finish() in your activity method onDestroy() in C and D classes, then if you go from C to D, Android will finish this Activity and you will go directly from D to B, instead of D to C.
I hope it will help you.
Make a global static boolean say closeActivity. Set it to false by default. When D is ended set the variable to true. In onResume of activity C check if variable is set to true and if true, call finish(). Do this until activity B is reached and in onResume of B set the boolean to false
Related
In my android application I have 3 activities A,B and C
Activity A is the launcher activity of my application, inside it there is a button with the following code when clicked:
startActivity(new Intent(this , B.class));
finish();
in activity B I have a button that starts activity C:
startActivity(new Intent(this , C.class));
In activity C, I need to finish the activity when the home button pressed:
public boolean onKeyDown(int keyCode,KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_HOME)
{
finish();
return true;
}
return super.onKeyDown(keyCode,event);
}
Now I expect that the top activity in my task is activity B, but when I tap the app icon from launcher activity A is started, so it seems the whole task is ended somehow.
Can someone explain what is going on and why am I getting this behavior?
Insert this code into your first activity and call it inside onCreate(...)
private void killIfIsnotTaskRoot() {
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
}
... a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created. In other circumstances — for example, if an existing instance of the "singleTop" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.
take a look at this link How to prevent multiple instances of an activity when it is launched with different intents
In the code you posted, activity B is trying to start activity B, NOT activity C.
in activity B I have a button that starts activity C:
startActivity(new Intent(this,B.class));
should be:
in activity B I have a button that starts activity C:
startActivity(new Intent(this,C.class));
I've been use
android:noHistory="true"
in my code so that I don't have many activities open at the same time.
The problem is the following:
Consider that I navigate navigate from Activity A (HomePage) to Activity B (noHistory=true) to Activity C. From Activity C, if I press the (hardware) back button, it takes me back to Activity A, not B. This is android:noHistory="true" , right? Is there a way to go back to Activity B and load it from scratch instead of going all the way back to Activity A?
Thanks!
You could just use something like this to go 'back' to any activity you'd like.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_BACK)
{
Intent intent = new Intent(startActivity.this, returnActivity.class);
startActivity(intent);
return true;
}
return false;
}
I ended up doing #Chandrakanth's method (thanks!); I passed extras to Activity C that will tell it what activity B to open when I press the back button.
Here is what the structure looks like:
Activity 1/2/3 -> Activity 4 -> Activity 5
On Act4, if a boolean variable is true, it jumps straight to Act5.
My problem is that when I press back on Act5, i want to get back to the activity which called Act4. But what happens is that it jumps back to Act5. If i use intent on back press, I i wouldn't know which activity called Act4.
in onCreate of Act4, i have this code:
if (boolean) {
Intent intent = new Intent(context, Act5.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
Is it okay to call finish first before the startActivity?
Thanks in advance.
Before calling intent to start act5 from act4 call finish() method.
boolean your_variable = true;
if(your_variable)
{
startActivity(new Intent(Act4.this, Act5.class));
finish();//now this finish() method will finish Act4 so when you press back on Act5 it will return back to Act3
}
My Suggestion is to use startActivityForResult() instead of startActivity(intent) and when you finish from activity5, you can set some flag and can manage while reaching onActivityResult()
if you want to finish activity4 based on flag, do finish() in onActivityResult()
in onCreate method of your Act4 class you can put
if (yourBooleanValue) {
finish();
startActivity(yourIntent);
}
or, it would be better if you would have that boolean in your 3rd activity..
you can manage by passing some value by putExtra by activity 1/2/3 and on activity 5 you can go back to activity according to those values.
I'm trying to do something similar to this question.
I've got a main app A, and sub-apps B and C. B is a searchable dictionary, and C is a definition, so if you search for many words, you can end up with the stack looking like A > B > C > B > B > C > B > C > C > C... etc
Whenever I go back, I'd like to go back to the original B, so I want the back stack to basically stay at A > B all the time.
I've currently got it set up using an Intent so when the back button is pressed from C, it goes to a new instance of B, but that's obviously not what I want.
Ideas?
Shouldn't hitting BACK from C take you to the original B? So the stack should look like:
A>
B>
C<
B>
C>
C<
C<
B<
A
with > going to the next activity, and < being the back button?
You could override onBackPressed for all the activities, so for C it loads a new B, B it loads a new A, and A you would do moveTaskToBack(true);, but that's less of a solution and more of a hack to make it work.
Try to use onResume so that B comes up like it would on default. Set any pertinent variables to what they are in a new activity. If you only want this when you're coming from C, have a class boolean that is set to true when C is loaded, and check it in onResume or onRestart. If it's true, set everything to default/blank, and set the boolean to false. If not, load it how it was (this is if they hit home and come back to the app, basically). I'm not at my work desk, but I think you'll want:
#Override
public void onResume() {
super.onResume();
if(fromC == true){
//Set all variables to load default dictionary
fromC = false;
}
}
}
This should make the original B act like a new B.
Or instead, you could do it the easy way, and when you call the intent to load a new B like this:
startActivity(getIntent());
finish();
That'll make there only be one B. Making it load as a blank when you go back is a little bit different and requires class variables, or some other tricky trick that I am thinking of. This is something like what you'll want to do: .zip of small sample
If you can get your code reworked to something like that almost (where you can use the appropriate variables to set up things to work right if that makes any sense).
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (splash.sdk < 5 && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
onBackPressed();
}
return super.onKeyDown(keyCode, event);
}
//This will make the back button exit the app to the home screen.
#Override
public void onBackPressed() {
moveTaskToBack(true);
return;
}
You can set an Intent flag to do this. Say you are in Activity C and you want to call Activity B: you add a flag to the Intent called FLAG_ACTIVITY_CLEAR_TOP. So:
class C extends Activity {
//...
private void gotob() {
Intent go = new Intent(this, B.class);
go.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(go);
}
//...
}
What this does is either to go to the top instance of B in the back stack (and clear everything else off the top), or create a new instance if none exists. I haven't worked out if there is a way to do this with launch flags though—there are some similar modes but I don't think any are identical.
Consider am having an application containing activity A,B,C. A is launched from the launcher and B is launched from A. B has a button. My requirement is on clicking button on B the present history of the activity Stack A->B should clear and the history stack must contain only C. Is it possible to do ? If so plz advise me...
Thanks in advance !
Although tedious, this can be done by launching using the Activity methods startActivityForResult(), setResult(), finish(), and onActivityResult().
In pseudo-code:
A: startActivityForResult(B)
B: startActivityForResult(C)
C: startActivity(D); setResult(CLEAR); finish()
D: ...
B: (onActivityResult) setResult(CLEAR); finish()
A: (onActivityResult) finish()
If you're willing to change your architecture a bit a more "natural" way to do this is to use FLAG_ACTIVITY_CLEAR_TOP for an easy way to go from A, B, C to just A.
A third way is to set A, B, and C to use noHistory, but then you would lose the ability to back out of C into B or A.
My "solution" is to override behaviour of Back button in activity C, so that it goes to phone launcher, not back the activity stack. This way, activities A and B remain on the back stack, but user has no way to navigate back to them. So the net result is same as if activity C was root activity.
/**
* Override "Back" key on Android 1.6
* Don't want user going back to Login or Register forms.
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
goHome();
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Override "Back" key on Android 2.0 and later
*/
#Override
public void onBackPressed() {
goHome();
}
private void goHome() {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}