Подтвердить что ты не робот

SavedInstanceState всегда имеет значение null

Это мой код saveInstaceState:

@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);
}

В журналах всегда отображается тег "Сохранение пакета".

Но в onCreate метод SavedInstanceState всегда имеет значение null.

4b9b3361

Ответ 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.

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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>

Ответ 5

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

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

  • Откройте свою активность.
  • Долгожданный домашний
  • Перейти к другому приложению
  • Долгожданный домашний
  • Вернитесь к своему приложению

Ответ 6

Не следует ли super.onSaveInstanceState(savedInstanceState); быть первой строкой в ​​вашем переопределении?

Изменить: War_Hero отмечает в комментариях, что документация по этому вопросу указывает, что нет, t - первая строка.

Ответ 7

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

<activity
    // ....
    android:noHistory="false" />

Ответ 8

Чтобы отладить, рассмотрите возможность внедрения onRestoreInstanceState и поместите вызов в Log.d в этом методе. Затем в эмуляторе нажмите ctrl-F11 или что угодно, чтобы повернуть телефон. Ваш звонок в Log.d должен быть удален.

Ответ 9

Внедрить метод onRestoreInstanceState и поставьте ниже код там

Altodo = savedInstanceState.getStringArrayList("todo_arraylist");

Ответ 10

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

Ответ 11

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

Ответ 12

https://developer.android.com/guide/topics/manifest/activity-element#lmode

Из этого видно, что "аналогично, если вы переходите к действию в текущем стеке, поведение определяется режимом запуска родительского действия". Возможно, вы находитесь в "стандартном" режиме.

Ответ 13

Я смог решить это с помощью:

@Override public boolean onSupportNavigateUp()
{
    onBackPressed();
    return true;
}

в манифесте все еще был установлен родительский элемент. Поэтому, когда вы нажимаете кнопку навигации вверх, теперь она действует как кнопка возврата.