android - 实例状态可序列化丢失数据
问题描述
在我的一项活动中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. 我放入mSelectedPositions
Bundle 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
保持不变。
解决方案
尝试放置一个 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())
}
}
...
}
推荐阅读
- c# - 使用 FluentValidation 根据布尔值的结果设置规则
- php - Mpdf 删除页脚并将其空间用于内容
- c++ - LLVM 编译:目标“../lib/IR/Release+Asserts/Intrinsics.gen.tmp”的配方失败
- sql-server - Eclipse/Maven:使用集成安全性的 QueryDSL 和 SQL Server 问题
- angular - 如何在角度6中的ngb-progressbar的值字段中分配动态值
- angular - 我可以在 Angular 6 单元测试中使用“this”吗?
- python - Virtualenv 需要 env
- c++ - SFINAE 是否依赖于类型扣除?
- ios - 在 SpriteKit 场景之间传递数据 (Swift)
- postgresql - 我们正面临“恐慌:无法从控制文件中读取:成功