Сериализуемое состояние экземпляра теряет данные - PullRequest
0 голосов
/ 21 октября 2019

В одном из занятий у меня есть HashSet<Integer> mSelectedPositions. Я хочу сохранить состояние этого набора при повороте экрана.

@Override
protected void onSaveInstanceState(@NotNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable(SELECTED_TYPES_POSITIONS, mSelectedPositions);
}

И восстановить его

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null && savedInstanceState.containsKey(SELECTED_TYPES_POSITIONS)){
        mSelectedPositions = (HashSet<Integer>) savedInstanceState.getSerializable(SELECTED_TYPES_POSITIONS);
    }
    ...
}

Проблема в том, что getSerializable(..) возвращает пустое HashSet, даже если оно не было пустым в putSerializable(..).

Что еще страннее, у меня есть почти такой же код (с другими ключами) в других фрагментах, и он отлично работает.

Не знаю, имеет ли значение, но рассматриваемая деятельность является дочерней по отношению к MainActivity.

Upd

Часть проблемы связана с процессом выбора. При уничтожении активности режим действия завершен.

@Override
protected void onDestroy() {
    if(mActionMode != null){
        mActionMode.finish();
    }
    super.onDestroy();
}

Что вызывает

@Override
public void onDestroyActionMode(ActionMode mode) {
    mAdapter.clearSelections();
    mActivity.nullifyActionMode();
}

в SelectionCallback.

Я думаю, что происходит следующее:
1. Я положил mSelectedPositions в outState Bundle, он хранит ссылку
2. Активность уничтожена
3. SelectionCallback очищает mSelectedPositions
4. Фактическая сериализация происходит с пустым HashSet.

Итак, я внес некоторые изменения - новый HashSet с копией mSelectedPositions data

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    outState.putSerializable(SELECTED_TYPES_POSITIONS, new HashSet<>(mSelectedPositions));
}

И он работает как надо.

Upd2

Во фрагментах я называю mActionMode.finish() в onDetach(), что не вызывается при повороте экрана, поэтому mSelectedPositions остается неизменным.

Ответы [ 2 ]

0 голосов
/ 23 октября 2019

Самое смешное, что сериализация outState происходит после onDestroy() вызова. И я стирал данные, переданные в outState в onDestroy.

Итак, есть два способа исправить это:
• передать копию данных в outState
• нестереть данные в onDestroy

Выбран второй вариант. Стирание может потребоваться в некоторых случаях в onDetach() фрагментов, но это не обязательно в Activity.

0 голосов
/ 21 октября 2019

Попробуйте поставить Json вместо необработанного HashMap

@Override
protected void onSaveInstanceState(@NotNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(SELECTED_TYPES_POSITIONS,new Gson().toJson(mSelectedPositions));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null && savedInstanceState.containsKey(SELECTED_TYPES_POSITIONS)){
        String data = savedInstanceState.getString(SELECTED_TYPES_POSITIONS);
       if(data != null){
       mSelectedPositions = new Gson().fromJson(str, new TypeToken<HashSet<Integer>>() { }.getType())
     }
    }
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...