首页 > 解决方案 > 实例状态可序列化丢失数据

问题描述

在我的一项活动中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(..)返回一个 empty HashSet,即使在putSerializable(..).

更奇怪的是,我在其他片段中拥有几乎相同的代码(带有其他键),而且效果很好。

不知道是否重要,但有问题的活动是 MainActivity 的子活动。

更新

部分问题在于选择流程。在销毁活动动作模式时完成。

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

哪个触发

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

SelectionCallback.

我想,接下来会发生:
1. 我放入mSelectedPositionsBundle outState,它存储引用
2. Activity 被销毁
3. SelectionCallback 清除mSelectedPositions
4. 实际序列化发生在空 HashSet 中。

mSelectedPositions所以我做了一些改变——带有数据副本的新 HashSet

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

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

它的工作方式应该如此。

更新2

在我调用的 FragmentsmActionMode.finish()onDetach(),屏幕旋转不调用它,因此mSelectedPositions保持不变。

标签: androidandroid-activity

解决方案


尝试放置一个 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())
     }
    }
    ...
}

推荐阅读