Я наблюдал точно такие же симптомы (сообщается как выпуск 133394 ) в проекте с двумя операциями A и B , которые распространяются на ActionBarActivity
. Действие A является основным действием, и я всегда получаю null
для savedInstanceState
в onCreate
его фрагмента списка при возвращении из вида подробного действия B . После многих часов эта проблема оказалась для меня скрытой навигационной проблемой.
Следующие сведения могут иметь отношение к моей настройке и исходить из других ответов на этой странице:
- Учитывая этот ответ, я убедился, что для каждого фрагмента и действия установлены уникальные идентификаторы.
- Нет переопределения
onSaveInstanceState
без super
вызова.
- Activity A указывается как acitivy B родительский в
AndroidManifest.xml
, используя атрибут android:parentActivityName
и соответствующий тег meta-data
для более ранних версий Android ( см. « Обеспечение навигации вверх »).
Уже без какого-либо соответствующего кода создания, такого как getActionBar()
.setHomeButtonEnabled(true)
, действие B имеет функциональную кнопку возврата ( <</strong>) на панели действий. При нажатии этой кнопки снова появляется действие A , но при этом (a) теряется все предыдущее состояние экземпляра, всегда вызывается (b) onCreate
и (с) savedInstanceState
всегда null
.
Интересно, что когда я нажимаю кнопку «Назад», расположенную в нижней части экрана эмулятора (открытый треугольник, указывающий влево), действие A появляется так же, как оно было оставлено (то есть его состояние экземпляра) полностью сохранен) без вызова onCreate
. Так может что-то не так с навигацией?
После больше чтения , я реализовал свои собственные навигационные инструкции для запуска в ответ на нажатие кнопки назад в действии B :
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home)
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
Ничего, связанного с восстановлением состояния активности экземпляра A не изменилось. NavUtils
также предоставляют метод getParentActivityIntent(Activity)
и navigateUpTo(Activity, Intent)
, который позволяет нам изменять намерение навигации, чтобы явно указать, что действие A не запускается заново (и, следовательно, без предоставления сохраненного состояния экземпляра) путем установки FLAG_ACTIVITY_CLEAR_TOP
флаг:
Если установлено, и запускаемое действие уже выполняется в
текущей задачи, а затем вместо запуска нового экземпляра этого
деятельность, все остальные виды деятельности будут закрыты и
это намерение будет доставлено (теперь на вершине) старой деятельности как
новое намерение.
В моих руках это решает проблему потерянного состояния экземпляра и может выглядеть так:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(this, intent);
return true;
}
return super.onOptionsItemSelected(item);
}
Обратите внимание, что это может быть неполным решением в других случаях, когда пользователь может напрямую переключиться на действие B из другой задачи (см. здесь ). Кроме того, возможно идентичное решение в поведении, которое не использует NavUtils
, заключается в простом вызове finish()
:
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()== android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Оба решения работают в моих руках. Я только предполагаю, что исходная проблема представляет собой слегка некорректную реализацию кнопки назад по умолчанию, и это может быть связано с тем, что эта реализация вызывает некий navigateUp
, который пропускает FLAG_ACTIVITY_CLEAR_TOP
.