This question already has answers here:
Finish parent and current activity in Android
(16 answers)
Closed 5 years ago.
I am currently stuck in the situation where I am currently in activity B which was called from activity A. So what I want is when a certain condition occurs in activity B then activity A is removed from the stack so that it will not be present when the user presses the back button. Removing all the activities is not an option because there are other activities before A which I don't want to destroy.I specifically need to destroy only activity A.
Simply finish the activity A when you are starting activity B.
Something like:
startActivty(intent);
this.finish();
this refers to current Activity (Activity A) and intent has the intent to open Activity B.
Edit: For removing the Activity A in certain condition only:
startActivityForResult(intent); // Starting Activity B.
Then in Activity B:
onBackPressed() {
setResult(...); // Set result as RESULT_OK etc based on condition. You can also send some data.
}
Then again in Activity A:
onActivityResult(...) {
if ( ... ) // check the condition value from the result
finish();
}
You can add flag with intent also, if you don't want to keep your activity in back-stack ,
Intent intent= new Intent(...);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
In Activity A
public class MainActivity extends AppCompatActivity {
public static Activity a;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
a=this;
}
......
}
In Activity B
public class SecondActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
//Finish Activity here, like on button click
btn= (Button) view.findViewById(R.id.close);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.a.finish(); //To finish MainActivity
}
});
}
}
When You Start Activity B From Activity A Just use finish()
Intent intent=new Intent(A.this,B.class);
startActivty(intent);
this.finish();
Related
I m trying to switch between two activities .
In activity 1, i have Button named GoToSecond to goto second activity.
In the same way,in activity 2, have Button named GoToFirst to goto first activity.
I have used log messages in first activity .
Order I m getting when GoToSecond button is clicked is
onCreate
onStart
onResume
onSaveInstance
onStop
and it switches to second activity .
Now in second activity when i click button GoToFirst , first activity opens and
log order in first activity is
onCreate
onStart
onResume ..
why onRestoreInstance is not getting called after onStart?
even if instance is stored??
Can anyne help me?
Here is the code of first activity:
public class MainActivity extends AppCompatActivity {
EditText hello;
Button b1;
public static String TAG="Prajwal";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hello=(EditText) findViewById(R.id.hello);
Log.d(TAG,"OnCreate counter 1");
b1=(Button) findViewById(R.id.b1);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(MainActivity.this,Main2Activity.class);
startActivity(i);
}
});
I havent added log messages in code .
And second activity code is
public class Main2Activity extends AppCompatActivity {
Button b2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
b2=(Button) findViewById(R.id.b2);
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(Main2Activity.this,MainActivity.class);
startActivity(i);
}
});
Log.d(MainActivity.TAG,"Oncreate 2");
}
For example
If i hv an EditText in first activity , and if i hav some text in it , I m losing that text while switching between 2nd activity to 1st activity . bcoz onCreate is called in first activity.
But when i switch to landscape mode onRestoreInstance is called and i m not losing any text .
As I know, onRestoreInstance will get called only if your activity will be destroyed and created again. So in this case your will restore previous state of destroyed activity.
But in your case activity isn't destroyed, it just stopped by the system, so it is not loose its state, so no need to restore it.
Please see these links for more details: FIRST, SECOND
Edited
Since you provided code of your Activities, as I see, you open from second activity not first activity, but third activity with type of first Activity.
So your stacktrace after pressing on button in second Activity would be:
MainActivity -> Main2Activity -> MainActivity.
So you have two simple solutions:
1) Instead of
Intent i=new Intent(Main2Activity.this,MainActivity.class);
startActivity(i);
Just write finish();
2) Add flag FLAG_ACTIVITY_CLEAR_TOP to intent from Main2Activity to MainActivity
In my android application suppose several activities are there
if using intent I go to other activities like this
[Activity A]->[activity B]->[Activity C]->[Activity-D]->[Activity N]
and now when am on activity N when I pressed button then I want to go to Activity B and want to destroy Activity C And Activity D but Activity A should not destroy. I also searched in various posts but I didn't get exactly the same solution.
Any help will be appriciated
In ActivityN, to return to ActivityB use this:
Intent intent = new Intent(this, ActivityB.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
Using the flag CLEAR_TOP will finish all activities in the stack that are on top of ActivityB. In the example you gave, this will finish ActivityN, ActivityD and ActivityC. Using the flag SINGLE_TOP will make sure that this will return control to the existing instance of ActivityB (ie: it won't create a new instance of ActivityB).
In Your Activity C do like this
public static ActivityC instance = null;
public class ActivityC extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
}
And in your Activity D do like this
public static ActivityD instance = null;
public class ActivityD extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
}
Finally in your Activity N. Do Something like this
public class ActivityN extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button yourButton= (Button) findViewById(R.id.yourButton);
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityC.instance.finish();
Activityd.instance.finish();
finish();
}
});
}
}
Here's my approach.
From Activity A, don't just start the Activity B, call startActivityForResult() method. Do this for all subsequent calls.
Now, when you press the button from Activity N, set the result for a custom value and call the finish() method for Activity N. Now you should hit the onActivityResult method on your Activity D. Now you can check whether the result was you pressing the button. Depending on your result, keep on setting the result and subsequently calling finish() on each Activity.
This should technically work.
Try this code:
//Activity A
Intent i = new Intent(getApplicationContext,ActvityB.class);
startActivity(i);
//Activity B
Intent i = new Intent(getApplicationContext,ActvityC.class);
startActivity(i);
//Activity C
Intent i = new Intent(getApplicationContext,ActvityC.class);
startActivity(i);
finish();
// finish here actvity which you want to finish
//Try this second way:
In your first activity, declare one Activity object like this,
public static Activity fa;
onCreate()
{
fa = this;
}
now use that object in another Activity to finish first-activity like this,
onCreate()
{
FirstActivity.fa.finish();
}
EDIT : Use startActivityForResult() instead of startActivity()
So depending on the result you can change the behavour.
Say for example When you wanted to go to ActivityB just return some flag in the INTENT. When it will be caught in Activity D and C in onActivityResult(), finish them and you will be finally on B.
Flag Intent.FLAG_ACTIVITY_CLEAR_TOP may solve your problem:
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
You can start ActivityC, ActivityD, ActivityN with the same request code passed to startForResult(requestCode)
And then at ActivityN, use finishActivity(int requestCode).
Documentation for finishActivity(int requestCode)
Force finish another activity that you had previously started with startActivityForResult.
Params:
requestCode – The request code of the activity that you had given to startActivityForResult().
If there are multiple activities started with this request code, they will all be finished.
When you press the back button while in an activity, by default, does the application not go back to the activity that called it? I am calling an activity in my application(call it Activity B), from Activity A, but when I hit the back button while in Activity B, I am taken back to the main page of the application.
So I guess in general, does pushing the back button on your phone take you to the calling activity?
Calling activity B from within an inner class of activity A:
class HeadlineButtonListener implements OnClickListener {
private Story story;
public HeadlineButtonListener(Story story) {
this.story = story;
}
#Override
public void onClick(View v) {
Intent myIntent = new Intent(HeadlineBoard.this, StoryView.class);
myIntent.putExtra(Constants.STORY_EXTRA, story);
HeadlineBoard.this.startActivity(myIntent);
finish();
}
}
You call finish() on first activity after firing the next activity, this will cause it to be removed from the activity stack, just remove the call to finish():
#Override
public void onClick(View v) {
Intent myIntent = new Intent(HeadlineBoard.this, StoryView.class);
myIntent.putExtra(Constants.STORY_EXTRA, story);
startActivity(myIntent);
}
I have two activities A, B . Now from A i call B by pressing a button (using startActivity()) , then press Back key to go back to A . Now when i press Button again to go to B , fresh activity is called (as expected).
Now can someone tell me how to show old previous state of B ?
I have read this article
Saving Android Activity state using Save Instance State , but couldn't help myself :(
public class B extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
if(savedInstanceState!=null){
EditText editText=(EditText)findViewById(R.id.editText1);
editText.setText(savedInstanceState.getString("EditBox"));
}
}
#Override
protected void onSaveInstanceState(Bundle onSaveInstanceState) {
System.out.println("B.onSaveInstanceState()");
super.onSaveInstanceState(onSaveInstanceState);
onSaveInstanceState.putString("EditBox","Hello");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
System.out.println("B.onRestoreInstanceState()");
super.onRestoreInstanceState(savedInstanceState);
EditText editText=(EditText)findViewById(R.id.editText1);
editText.setText(savedInstanceState.getString("EditBox"));
}}
My Class A
public class A extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(StartActivityforresultActivity.this,B.class);
startActivity(i);
}
});
}
With what it sounds like you're trying to do you have two options:
1. Save the state of B when B's onDestroy or onBackPressed is called. You'll have to save this to memory or write it out using some sort of persistence (SharedPreferences, local file, etc). Then whenever B is started, check to see if that data exists and use it to load the state.
2. Override onBackPressed so that when it is pressed you aren't calling super.onBackPressed. Instead start an instance of activity A and set your intent's flags to be FLAG_ACTIVITY_REORDER_TO_FRONT before calling startActivity. So something like this:
Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
Now when you hit back, it should find the instance of A that is in your activity stack and just bring it to the front. You may have to add the same flag whenever you start B as well.
In my application I have an activity class A that has a listview with a cursor adapter.
From A I can go to the activity B, by pressing a button. From B I can go back to A by pressing a button (not by pressing the BACK button). This means that a new instance of the A activity is created.
From this point, if I press the BACK key, the current A activity is destroyed and B is popped. And if I press BACk again the initial A activity is popped. I hope it is clear.
My problem is that when the second A activity is destroyed, the database connection is reseted, in a static manner. So in the end, when the initial A activity is displayed, the listview will be empty.
My question is: should I try to have a single instance for the A activities, or shoud I change the database connection (to link it with the activity instance)?
Thanks a lot
Gratzi
First Of All In class A which is carrying your ListView . on clicking any Listview call the startActivity method for the Class B Activity without calling any finish().
I hope which is you are already doing.
Now in the Second Activity The button (Not the Back Button) you are using for calling Activity A . in its clickListener for calling Activity A dont call the startActivity(intentForA) instead call the finish(); for ending the Activity B. this will resume the A activity which is paused..
I hope this will help
You will need to create 3 Activities rather than 2.
Have a MAIN activity that does not really display anything.
So You have Activity A that is your main activity that can handle the connection to the DB etc.
Then Activity B and C can be the A and B that you have used.
Activity A (Main activity) can have a static instance of itself so you can refernce it's
Variables etc -OR- you can pass data from one activity to the other using Intent.put, etc.
I prefer the global static instance way as I'm a little old school on Java.
Edit:
Forgot to mention, to handle the 'closing' of the app, either Activity B or C must also close Activity.
public class ActivityA extends Activity {
ActivityA act_a_instance;
public int some_integer = 22;
#Override
public void onCreate(Bundle savedInstanceState) {
act_a_instance = this;//Now you can reference this Activity outside
//Your creation stuff etc
}
}
public class ActivityB extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
//Your creation stuff etc
//Reference stuff from ActivityA like so :
int temp_integer = ActivityA.act_a_instance.some_integer;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.options_back:
startActivity(new Intent(this, ActivityC.class));
break;
}
}
#Override
protected void onStop() {
finish();
super.onStop();
}
}
public class ActivityB extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
//Your creation stuff etc
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.options_back:
startActivity(new Intent(this, ActivityB.class));
break;
}
}
#Override
protected void onStop() {
finish();
super.onStop();
}
}
Use below code hope this will solve your problem
Intent i = new Intent(B.this, A.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);