I have two activities, A and B. When activity A is first started, it accesses the Intent
passed to it (because the Bundle
is null
, as it should be the first time through), and displays information accordingly:
CustInfo m_custInfo;
...
protected void onCreate(Bundle savedInstanceState)
{
...
Bundle bundle = (savedInstanceState == null) ? getIntent().getExtras() : savedInstanceState;
m_custInfo = (CustInfo) m_bundle.getSerializable("CustInfo");
if (m_custInfo != null
...
}
This works fine the first time through. The EditText
controls and ListView
are filled out correctly.
Now, when an item in the list is clicked, activity B is started to show the details:
m_custInfo = m_arrCustomers.get(pos);
Intent intent = new Intent(A.this, B.class);
intent.putExtra("CustInfo", m_custInfo); // CustInfo is serializable
// printing this intent, it shows to have extras and no flags
startActivityForResult(intent, 1);
Right before acivity B is started, the framework calls A's overridden onSaveInstanceState()
:
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putSerializable("CustInfo", m_custInfo);
}
In activity B, when the Up button is pressed in the action bar, I want to return to activity A and have it be in the same state as it was before:
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
Intent intent = NavUtils.getParentActivityIntent(this);
// printing this intent, it shows to have flags but no extras
NavUtils.navigateUpFromSameTask(this); // tried finish() here but that created an even bigger mess
return true;
}
...
}
Herein lies the problem, when in onCreate()
of activity A the second time, the Bundle
parameter is null
and getExtras()
returns null
. Since onSaveInstanceState()
was called, I would have expected the Bundle
parameter to be non-null
.
I've read about this issue on other web sites, have tried the suggestions, but nothing works.
If you want your application to react this way, you should declare the launch mode of your activity A as:
android:launchMode="singleTop"
in your AndroidManifest.xml.
Otherwise android uses standard launch mode, which means
"The system always creates a new instance of the activity in the target task"
and your activity is recreated (see Android documentation).
With singleTop the system returns to your existing activity (with the original extra), if it is on the top of the back stack of the task. There is no need to implement onSaveInstanceState in this situation.
savedInstanceState is null in your case, because your activity was not previously being shut down by the OS.
Notice (thanks, android developer for pointing to this):
While this is a solution to the question, it will not work if the activity one returns to is not on the top of the back stack.
Consider the case of activity A starting B, which is starting C, and C's parent activity is configured to be A.
If you call NavigateUpFromSameTask()
from C, the activity will be recreated, because A is not on top of the stack.
In this case one can use this piece of code instead:
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
NavUtils.navigateUpTo(this, intent);