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);
}
Related
Suppose I have activities named A, B, C, D. Now, consider A has been launched as the root activity and B has been launched from A and C has been launched from B and D has been launched from C.
Now I have a button named "Success" in the activity D. If suppose, I press the button "Success" in the activity D, then the activity C should be removed from the history stack and go to activity B, but on Pressing back key from the activity D should display activity C instead of B and Clear D from stack. Please can anyone help me to resolve this problem?
Add this Code in your Activity_D for Button click
btnSuccess.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Activity_D.this, Activity_B.class));
finishAffinity();
}
});
Also add this in your Activity_D to Handle Back Button Pressed.
#Override
public void onBackPressed() {
finish();
super.onBackPressed();
}
From Activity_C to Activity_D
startActivity(new Intent(Activity_C.this, Activity_D.class));
Don't call finish() here.
When you click on Success button, you can use the following line of code to open your B activity:
Intent d_intent = new Intent(D.this, B.class);
d_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
d_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(d_intent);
finish();
Here Activity B will be started from the back stack rather than a new instance because of Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_NEW_TASK clears the stack and makes it the top one. So when we press the back button the whole application will be terminated. And on Back press you need to simply call
finish();
Hope it will help you out.
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));
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
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.
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.