saveInstanceState всегда равно нулю - PullRequest
65 голосов
/ 02 июля 2011

Это мой сохраненный код состояния:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
    savedInstanceState.putStringArrayList("todo_arraylist", Altodo);
    Log.v("bundle", "Saved");
    super.onSaveInstanceState(savedInstanceState);
}


public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    if (savedInstanceState != null) 
    {
        Altodo = savedInstanceState.getStringArrayList("todo_arraylist");
        Log.v("bundle", "Restored");
    }
    else
    {
        Log.v("bundle", "null");
    }

    setContentView(R.layout.main);
}

В журналах всегда отображается тег "bundle save".

Но в методе onCreate, SavedInstanceState всегда равно нулю.

Ответы [ 11 ]

49 голосов
/ 06 апреля 2015

Я наблюдал точно такие же симптомы (сообщается как выпуск 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.

14 голосов
/ 12 августа 2011

Вы проверили, установлен ли у вас Id для этого вида (если вид есть / имеет ...).onSaveInstanceState () не вызывается иначе.

Проверить ссылку .

13 голосов
/ 11 февраля 2012

Сохраненное таким образом состояние не сохраняется.Если все приложение уничтожается, как вы делаете во время отладки, пакет всегда будет нулевым в onCreate.

Этот IMO - еще один пример ужасной документации Android.Именно поэтому большинство приложений на рынке не поддерживают сохранение состояния должным образом (вообще).

7 голосов
/ 15 мая 2015

в манифесте добавить эту строку для действий

android:launchMode="singleTop"

например:

<activity
        android:name=".ActivityUniversity"
        android:label="@string/university"
        android:launchMode="singleTop"
        android:parentActivityName="com.alkhorazmiy.dtm.ActivityChart">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.alkhorazmiy.dtm.ActivityChart" />
    </activity>
3 голосов
/ 02 июля 2011

Разве super.onSaveInstanceState(savedInstanceState); не должно быть первой строкой вашего переопределения?

Редактировать : War_Hero указывает в комментариях, которые указаны в документации по этой теме что нет, это не должна быть первая строка.

3 голосов
/ 02 июля 2011

Как вы это тестируете?

По моему мнению, лучший способ протестировать его - использовать флаг "Не выполнять действия" в меню "Настройки"> "Параметры разработчика".Если у вас нет параметров разработчика в настройках, см. Включение параметров разработчика на устройстве .

  1. Откройте свое занятие
  2. Нажмите и удерживайте кнопку home
  3. Переход к другому приложению
  4. Долгое нажатие домой
  5. Возврат к вашему приложению
1 голос
/ 21 августа 2016

Проверьте свою активность в AndroidManifest.xml и удалите свойство android:noHistory, если это правда.

<activity
    // ....
    android:noHistory="false" />
0 голосов
/ 04 сентября 2018

Мне удалось сделать то же самое.Вместо обработки saveInstanceState Bundle в методе onCreateView я обработал его в методе onCreate и установил переданное значение в переменную globar, а затем обработал эту переменную в методе onCreateView.Надеюсь, это поможет.

0 голосов
/ 27 января 2017

Я обнаружил, что при переопределении onSaveInstanceState() и сохранении некоторых данных в Bundle состояние экземпляра восстанавливается.В противном случае это не так.

0 голосов
/ 02 июля 2011

Реализация метода onRestoreInstanceState и поместите ниже код там

Altodo = savedInstanceState.getStringArrayList("todo_arraylist");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...