Android on back pressed previous activity is restarted instead of resumed - android

This is a follow up question to this question:
How to resume activity instead of restart when going "up" from action bar
I got 2 activities, both are defined in the manifest with android:launchMode="singleTop".
Activity A calls activity B. Activity B got a back button:
backButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
finish();
}
});
On some devices there is no problem and the previous activity resumes. Other devices are restarting the previous activity instead of resuming it. Why is that?

This could be because on some devices your activity is being garbage collected to save memory. If you want to resume instead of restart even in the case of android killing your activity override the onSaveInstanceState method, and save all your variables in the bundle.
Now when you go back to your activity, if it was killed then in on create a bundle will be passed called savedINstanceState. If savedInstanceState is not null then use the data present in it to bring your activity back to the previous state.
more details here: How to use onSaveInstanceState() and onRestoreInstanceState()?

Related

Activity backstack handling

Suppose I have activities A, B, C, D, E.
when I open application with activity A and switch to activity B and further to activity C. Suppose, somehow B gets destroyed by system. and when I press back button, I came out of app. What I really wanted was to be able to go to B if it exists otherwise A (landing page). In normal cases it's working smoothly but it's some cases where I have to interact with other apps/interfaces for eg. open url in browser. After sometime if I go back to app, I see latest page as it is but when I press back button app exits.
I have searched for solutions but couldn't find one so posting it as a question.
I know the idea of passing extra in intent and starting new intent on back press but these would not work in some cases or requires creating a backstack handler of own.
There is no guarantee that your activities will stay in memory and this is an intentional behaviour.
Your option is use to onRestoreInstanceState and onSaveInstanceState so that user do not lose critical data.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// Get data
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// Save data
super.onSaveInstanceState(outState);
}
One way which I have used in the past to validate activity state is to add e.g. a boolean attribute in your activity, set this true when activity starts, if your activity is destroyed after some time this will be false. Check state by overriding the activities onBackPressed method?
e.g.
onBackPressed(){
if status{
/*activity live*/
}
else{
/*activity destroyed/*
}
}
This might work If I understand you issue correctly.

singleInstance launch mode: why is onCreate called after activity is brought to front?

I launch main activity, change some settings in UI, press back button and then reopen the activity. onCreate() is called again and activity is back to default state. Why is this?
I would expect only onResume() to be called since I have this in Manifest:
android:launchMode="singleInstance"
Try using moveTaskToBack(true); in onBackPressed() to make your current activity hide instead of destroying, so you can reopen it again
#Override
public void onBackPresses(){
moveTaskToBack(true);
}
I launch main activity, change some settings in UI, press back button and then reopen the activity. onCreate() is called again and activity is back to default state. Why is this?
This is expected behavior of activity life cycle. When you press back button then activity get destroyed, it will start from onCreate method.
This is because when you press back, it destroyes the activity.
I think that what you want is to keep the state when you come back to this activity, not really to have one instance of it. So you should save the information you need and then restore them in onCreate.
Single instance only means (if I remember it well) that if you launch multiple activities without finishing them, the ones that have singleInstance will go back to front when you will call startActivity() and will not call onCreate. But this means you can't have this behavior by pressing back.
Maybe you can override onBackPressed and start another activity (the one you should go back to) instead of calling super.onBackPressed(). this should do what you want but if think it will be kind of difficult to manage.
By the way remember that Activities might be killed by the system itself, so you should not rely on the fact that your activity as not been killed

Return to previous Activity without deleting current state - Android

I wrote an Android app with several Activities and a Main Activity. When I go from the Main Activity to lets say Activity B, I want to "pause" the Main Activity, when the back button is pressed it should go back and reactivate the Main Activity instead of calling onCreate().
This shall work with all Activities, so if I click on a button to start Activity B, it shall also reactivate the old Activity B instead of creating a new state with onCreate().
How can I realize this?
PS: I already tried it with parcelable, but this do only work, if I close the application or something unexpected happens.
It's always possible that the first activity may be destroyed when you start another activity. It will be recreated when you go back to it. Every app should be written with this possibility in mind. To make sure your activities can handle being destroyed and recreated, turn on the "don't keep activities" developer option.
It is by default in Android. If you Start Activity B from Activity A then activity A goes in stopped state. Below methods will be called of Activity A
onPause()
onStop()
When you tap on Back key on Activity B. Below methods of Activity A will be called.
onRestart()
onStart()
onResume()
For reactivating Activity B, you can set Activity B launch mode as singleInstance. This will make sure that only single instance of Activity B will be created. onCreate will be not be called again. onNewIntent will be called when that activity is reactivated.
Refer: http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Activities live in stack order. Each activity has its life cycle. When you close an activity (Activity B in your example) it eventually reaches onDestroy() method and removed from the stack order. It is by default in Android and there's nothing you can do about it.
What you can do is rewrite the onStop() method in Activity B and save some activity data (like text in EditText, for example) in SharedPreferences - read here. Then in your onCreate() method you can call for SharedPreferences, check if it's not empty and restore the text in the EditText by pulling appropriate value by key.

Dealing with SavedInstances, and restoration of activity

basically my app has 2 activities.Say "A" and "B"
.
A launches B.
Activity B plays music and also has a notification.
Case 1:when the view is still on activity B` i press home button and then i click on the the notification, activity B is opened with its view intact and with its music playing (because in the manifest i am using android:launchMode= "singleTop" and hence another instance of the activity is not created) this part is as desired......
but
Case 2:when the view is on activity B and i press back button ,activity A appears and then i click on the the notification, activity B is opened with the view lost and music also stops(not desired)......i am making a guess that it happens because when i press the back button the activity is destroyed ,so i have to progamatically restore its view right??so to restore its view i override two methods .....
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putBoolean("boolMusicPlaying", boolMusicPlaying);
savedInstanceState.putInt("swapnumber", swapnumber);
savedInstanceState.putString("seekbarprogress", progress2);
savedInstanceState.putInt("position.seekbar",seekbar.getProgress());
savedInstanceState.putString("seekmaxString", max2);
savedInstanceState.putInt("seekmaxInt",seekMax);
savedInstanceState.putParcelableArrayList("songfetails",songdetails);
super.onSaveInstanceState(savedInstanceState);
}
//make a note ....even if i don't override onDestroy() and don't call on SaveInstanceState explicitly, then too i am not getting any desired effect.......
#Override
public void onDestroy()
{ Bundle savedState = new Bundle();
onSaveInstanceState(savedState);//because of this line....the app is crashing......
super.onDestroy();
}
but it didn't help.....
and in on create i am putting a check if saved instances is null or not....create view accordingly...(i.e from saved instances or from fresh) but it didn't help...
also this line is giving a crash ...onSaveInstanceState(savedState);
even if i don't override ondestroy() and kill the app manually from task killer,and then try to open activity B,then too the saved instances thing should work right,because the method OnSaveInstanceState will be automatically called then,right???please help
Basically if you have pressed a back button,restoration of activity should be done using shared preferences/or a database but if you haven't pressed the back button and then you want to restore the state of the activity (because the activity was destroyed by the system ) then the bundle savedinstances can be used ...
From Android documentation:
When your activity is destroyed because the user presses Back or the activity finishes itself, the system's concept of that Activity instance is gone forever because the behavior indicates the activity is no longer needed. However, if the system destroys the activity due to system constraints (rather than normal app behavior), then although the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed. The saved data that the system uses to restore the previous state is called the "instance state" and is a collection of key-value pairs stored in a Bundle object.
To fix second problem you must restore data form some other source (service that plays music, restore info from application context or singleton, etc.)
For more info check this.

Activity recreates even though no one calls it

I have an activity A which shows different screens. I chose to show multiple views in the same activity, by using setContentView.
When you launch the app, Activity A shows the default screen. You then choose an option and the activity shows you another set of options by setting setContentView to another view. This new view now takes you to a new activity(Activity B) when you click it, and Activity A calls finish()
If I now end Activity B, by calling finish() on it, I am being taken back to Activity A, and it calls it's onCreate(). I can't figure out what's wrong here. Why would an activity recreate itself when Activity B never called an intent for Activity A?
view.findViewById(R.id.quit).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
The issue is most likely because the purpose of onCreate() is to create the Activity's state as it was when it left. You can't under any circumstances assume that an Activity will maintain its state once the user leaves it. Views are memory intensive, and the system is going to dump it as soon as it needs more memory for the current top Activity. If this happens then the system must recreate the Activity to its original state before the system dumped it.
You can save states via the onSaveInstanceState(Bundle) method. The bundle that's passed in to onCreate is the same bundle you set in onSaveInstanceState(), so all parameters will be there. Then you can rebuild just as it was.

Categories

Resources