An app has 2 activities, A and B.
A has instance data that is saved
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("foo", 0);
}
and A has
int bar;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
if (savedInstanceState != null) {
bar = savedInstanceState.getInt("foo");
} else {
bar = -1;
}
}
to restore the data.
Activity B has the actionbar enabled and
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
// ...
}
to enable up navigation. Also A is listed as the parent activity of B in AndroidManifest.xml
.
When a user navigates from A to B onSaveInstanceState
is called and if they navigate back to A
using the back button activity A correctly restores it's saved information.
However when the user navigates from A to B onSaveInstanceState
is called and then up navigation is used to return to A the onCreate(Bundle savedInstanceState)
is passed null
even though information was saved.
How do I get up navigation to pass the the Bundle created in onSaveInstanceState
?
I faced the same issue - I simply wanted to have two activities A and B, where A is the parent of B. When you are in B and click the Up button, you return to A and in onCreate()
you restore your data from the Bundle. However, the bundle is always null
.
In most cases, people recommend setting android:launchMode="singleTop"
for the activity in the manifest. This is, actually, not necessarily a desired behaviour, because it simply means that when you click the Up button, the parent will not be recreated. You might find this OK, but in my case I definitely wanted to have the parent recreated to mirror some changes in the DB.
Other solutions say to attach a listener to the Up button and add this code:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpFromSameTask(this);
break;
}
return super.onOptionsItemSelected(item);
}
This achieved no effect for me. I don't actually understand what this code is supposed to do.
Still, I think I found an answer to the question in another post. Check it here.
It's said:
When you press back, the Activity is destroyed and the data it had is lost. After this you will always get null in the bundle as a new, fresh instance is being created when you reopen the app.
The Bundle savedInstanceState is used when the activity is being recreated due to some changes (like rotation), or because it was paused in the background for a long time.
If you want to persist some data, consider SharedPreferences for small stuff, or maybe a database (SQLite, Realm) or files for large stuff.
I guess that the approach with the bundle is simply not the way Android expects us to do it. You should use a SharedPreferences
object and save your foo
variable inside it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With