Ответ 1
Я наблюдал те же самые симптомы (в качестве проекта issue 133394) в проекте с двумя активностями A и B, которые расширяют ActionBarActivity
. Активность A - это основное действие, и я всегда получаю null
для savedInstanceState
в onCreate
его фрагмента списка при возврате из активности подробного представления B. Спустя много часов эта проблема оказалась для меня проблемой маскировки.
Следующие действия могут иметь отношение к моей настройке и доступны из других ответов на этой странице:
- Учитывая этот, я убедился, что каждый фрагмент и активность имеют уникальные идентификаторы.
- Отмена
onSaveInstanceState
без вызоваsuper
отсутствует. - Действие A указано как acitivy B родительский в
AndroidManifest.xml
, используя как атрибутandroid:parentActivityName
, так и соответствующий тегmeta-data
для более ранних версий Android ( см. "" Предоставление навигации").
Уже без соответствующего кода создания, такого как getActionBar()
.setHomeButtonEnabled(true)
, активность B имеет функциональную кнопку возврата (<) в панели действий. Когда эта кнопка нажата, появляется активность A, но с (а) все предыдущее состояние экземпляра потеряно, (b) onCreate
всегда вызывается и (c) 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
.