使用 Serializable 在 onSaveInstanceState 中保存对象引用?
Saving object reference in onSaveInstanceState using Serializable?
我需要说明如何保存引用了另一个对象的对象的状态?
假设我有以下 class 个对象需要保存和恢复:
public class ObjectA implements Serializable{
private List<ObjectB> mObjectBList;
}
public clas ObjectB implements Serializable {
// some other members here
private ObjectA mParent;
}
以下是在片段中调用保存和恢复的代码:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("ObjectA", mObjectA);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mObjectA = (mObjectA) savedInstanceState.getSerializable("ObjectA");
}
}
问题:
- 保存 mObjectA 是否也会保存 mObjectBList 中的每个对象?
- 既然 mObjectB 有一个对其父 ObjectA 的引用,是否会为每个 ObjectB 重新实例化 ObjectA?然后又会重新实例化 ObjectB,然后它会重新实例化 ObjectA,等等,导致无限循环?
- 你会如何解决这个问题?
我不清楚当一个对象被保存为可序列化时会发生什么,所以请帮助我理解 Android 如何区分何时实例化一个新对象以及何时它会重现一个实际的引用。
是的。但是 List
不是 Serializable
。例如,将 List
更改为 ArrayList
。
它工作正常。 Java 序列化适用于循环引用。
Here 是类似的问题。
我觉得没问题
我用下面的代码做了测试。
public class MainActivity extends AppCompatActivity {
private ObjectA mObjectA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
mObjectA = (ObjectA) savedInstanceState.getSerializable("ObjectA");
// check mObjectA == mObjectA.getObjectBList().get(0).getParent();
} else {
mObjectA = new ObjectA();
ArrayList<ObjectB> list = new ArrayList<>();
list.add(createB());
list.add(createB());
list.add(createB());
list.add(createB());
list.add(createB());
mObjectA.setObjectBList(list);
}
}
private ObjectB createB() {
ObjectB objectB = new ObjectB();
objectB.setParent(mObjectA);
return objectB;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("ObjectA", mObjectA);
}
}
public class ObjectA implements Serializable {
private ArrayList<ObjectB> mObjectBList;
public void setObjectBList(ArrayList<ObjectB> objectBList) {
mObjectBList = objectBList;
}
public ArrayList<ObjectB> getObjectBList() {
return mObjectBList;
}
}
public class ObjectB implements Serializable {
// some other members here
private ObjectA mParent;
public void setParent(ObjectA parent) {
mParent = parent;
}
public ObjectA getParent() {
return mParent;
}
}
我需要说明如何保存引用了另一个对象的对象的状态?
假设我有以下 class 个对象需要保存和恢复:
public class ObjectA implements Serializable{
private List<ObjectB> mObjectBList;
}
public clas ObjectB implements Serializable {
// some other members here
private ObjectA mParent;
}
以下是在片段中调用保存和恢复的代码:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("ObjectA", mObjectA);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mObjectA = (mObjectA) savedInstanceState.getSerializable("ObjectA");
}
}
问题:
- 保存 mObjectA 是否也会保存 mObjectBList 中的每个对象?
- 既然 mObjectB 有一个对其父 ObjectA 的引用,是否会为每个 ObjectB 重新实例化 ObjectA?然后又会重新实例化 ObjectB,然后它会重新实例化 ObjectA,等等,导致无限循环?
- 你会如何解决这个问题?
我不清楚当一个对象被保存为可序列化时会发生什么,所以请帮助我理解 Android 如何区分何时实例化一个新对象以及何时它会重现一个实际的引用。
是的。但是
List
不是Serializable
。例如,将List
更改为ArrayList
。它工作正常。 Java 序列化适用于循环引用。 Here 是类似的问题。
我觉得没问题
我用下面的代码做了测试。
public class MainActivity extends AppCompatActivity {
private ObjectA mObjectA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
mObjectA = (ObjectA) savedInstanceState.getSerializable("ObjectA");
// check mObjectA == mObjectA.getObjectBList().get(0).getParent();
} else {
mObjectA = new ObjectA();
ArrayList<ObjectB> list = new ArrayList<>();
list.add(createB());
list.add(createB());
list.add(createB());
list.add(createB());
list.add(createB());
mObjectA.setObjectBList(list);
}
}
private ObjectB createB() {
ObjectB objectB = new ObjectB();
objectB.setParent(mObjectA);
return objectB;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("ObjectA", mObjectA);
}
}
public class ObjectA implements Serializable {
private ArrayList<ObjectB> mObjectBList;
public void setObjectBList(ArrayList<ObjectB> objectBList) {
mObjectBList = objectBList;
}
public ArrayList<ObjectB> getObjectBList() {
return mObjectBList;
}
}
public class ObjectB implements Serializable {
// some other members here
private ObjectA mParent;
public void setParent(ObjectA parent) {
mParent = parent;
}
public ObjectA getParent() {
return mParent;
}
}