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));
Related
I am working on an app on which you can share images from your local phone's gallery app. Whenever a photo is shared through the gallery app, an Activity A opens up in my app.
The photo sharing follows some steps in which it goes from Activity A to Activity B and the final step in B opens the Main Activity.
What I want, pressing back from B should open A. Pressing the final button in B should clear both A and B from backstack, so that if you press back on Main Activity, the app should close.
What I did :
Initially, I was opening Main Activity with this flag intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
But, this started a new task and so even when I used to close my app and go to the phone's gallery app, it would show A instead of the photo on that app, when you pressed back, then you could see the actual image in that gallery app.
I had specified android:noHistory="true" for A and B and started the intent to Main Activity without the new task flag. This solved the new task problem in the sense that when I close my app and switched back to the gallery app, it showed the actual image not my activity A. But the issue here is, I can't go back to A from B, also if the app is minimised, then also the activity is gone.
Create a singleton class :
Stack<Activity> stack;
public void add(Activity activity){
stack.add(activity).
}
public void remove(){
Activity activity = stack.lastElement();
if(activity != null) {
stack.remove(activity).
activity.finish();
}
}
public void removeAll() {
for (Activity activity : stack) {
if (activity != null)
activity.finish();
}
stack.clear();
}
call add() in your activities' onCreate()
call remove will finish current activity
call removeAll will finish all activities added into the stack
Intent l = new Intent(getApplicationContext(), MainActivity.class);
l.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
l.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
l.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
finish();
startActivity(l);
use this on finish button in avtivity B.
I have created two activity i.e Activity A & Activity B ,if i clicked Next Button i.e in Activity A going to Activity B properly But when i click on back button i want to go from Activity B to Activity A and page swipe from left side to right side and on click next page swipe right to left,
here is my code
public void onBackPressed() {
Intent intent = new Intent(ActivityB.this, Activity.class);
startActivity(intent);
finish();
Just Remove finish() from Activity.
Because when you go to second activity and finish first activity, there is no any activity and stack.
So If you click back button from second activity, application will be finish if there is no Activity in stack.
You should use this Approach.
Ex.
In Activity.java
Intent first = new Intent(Activity.this,ActivityB.class);
startAcivity(first);
// Don't use finish() here.
In ActivityB.Java
Just click on built in back button.
or If you want to use your own back button.
Use finish(); in button click event.
You can use only onBackPressed();
public void onBackPressed() {
super.onBackPressed();
}
Android Overriding onBackPressed()
How to go previous Activity by using back button
No need to put an intent and start a new activity that would take you to previous activity.
Just call 'finish()'
It would go back to previous activity as Android activities are stored in the activity stack
If you have other activities that are present in between the activites say if android stack is filled with Activity A>Activity C>Activity B,If you want to go to Activity A on finish of Activityy B then you have to set an intent flag like FLAG_ACTIVITY_REORDER_TO_FRONT or FLAG_ACTIVITY_PREVIOUS_IS_TOP
Just use finish() no need for intent as A is already in stack and when you finish B, A will come to surface
public void onBackPressed() {
finish();
}
Read this to learn more about android activity stack.
public void onBackPressed() {
// TODO Auto-generated method stub
finish();
super.onBackPressed();
}
Given:
6 activities. (A, B, C, D, E, F)
Each activity consists of several edittexts or a camera implementation and a next button to goto next activity (The activity which is going to be opened depends on the value entered by the user).
If edittexts are displayable or not comes from the server.
Incase there are no edittexts on the layout then only next button is shown.
Flow of the application: A->B->C(->D)->E->F
The Activity D opens only when a certain condition is met in activity C.
Todo:
Incase, The activity contains no edittext and only next button i should be able to skip this activity.
If the flow of my application is like: A->B->C->E->F Then when i press hard back the flow should be F->E->C->B->A
If the flow of my application is like: A->B->C->D->E->F Then when i press hard back the flow should be F->E->C->B->A
If the flow of my application is like: A->C->D->E->F Here we skipped B because there are no views in Activity B, When i press hard back the flow should be F->E->C->A
what i did:
To skip the activity when no fields are available inside onCreate(), I am checking if any field is displayable if no then i add the activity name in a stack if it is not present in it and then open the next activity.
// Block for skipping this screen
if (skipScreen) {
Intent i = new Intent(B.this, C.class);
startActivity(i);
finish();
} else {
if (!Constants.st.contains(B.class)) {
Constants.st.push(B.class);
}
}
And when i press back from an activity i pop() the name of that activity from the stack and peek() at the top of the stack and jump to that activity.
public void onBackPressed() {
super.onBackPressed();
Constants.st.pop();
Intent i = null;
if (Constants.st.isEmpty()) {
i = new Intent(B.this, A.class);
} else {
Class<Activity> jumpTo = Constants.st.peek();
i = new Intent(B.this, jumpTo);
}
startActivity(i);
finish();
}
I think the statePattern will be very helpfull. Here is a short tutorial.
I have an activity(A) and I need to set some text after activity becomes visible to user ,first time I navigate to activity everything is OK,but when I navigate from (A) to activity (B) and press back button ,it returns to (A) button doesn't call onstart of (A).what is the problem?
Back button is navigation to previous activity in activity stack, which is already created and thus its onResume method will be called. So you can do what you want inside onResume().
If it is must for your activity to create new instance do as follows:
If you are on activity A and going B, call A.finish() so it discards A from activity stack, and on B override backPressed and create a new instance of A.
#Override
public void onBackPressed() {
Intent i= new Intent(this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.finish();
startActivity(i);
}
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);
}