我正在使用以下代码在 Android 内部存储器中保存和检索对象。我已经成功地使用字符串对象对其进行了测试。当我尝试保存位图时,出现 IOException。 (我发现我必须调用压缩方法)所以我注意到我可以保存一些对象,保存对象有什么限制?
当我保存一个对象时,它只保存字段吗?我可以保存包含其他对象的对象吗?请清理我。
代码:
public Object readObjectFromMemory(String filename) {
Object defautObject = null;
FileInputStream fis;
try {
fis = game.openFileInput(filename);
ObjectInputStream is = new ObjectInputStream(fis);
defautObject = is.readObject();
is.close();
this.gameEngineLog.d(classTAG, "Object successfully read: " + filename);
}
catch (FileNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "FileNotFoundException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (StreamCorruptedException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "StreamCorruptedException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (IOException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "IOException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "ClassNotFoundException");
this.gameEngineLog.d(classTAG, "Object couldn't be opened: " + filename);
}
return defautObject;
}
public void writeObjectToMemory(String filename, Object object) {
FileOutputStream fos;
try {
fos = game.openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(object);
os.close();
this.gameEngineLog.d(classTAG, "Object successfully written: " + filename);
}
catch (FileNotFoundException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "Object couldn't be written: " + filename);
}
catch (IOException e) {
e.printStackTrace();
this.gameEngineLog.d(classTAG, "Object couldn't be written: " + filename);
}
}
提前致谢。
最佳答案
限制是所有对象都必须是可序列化的(实现接口(interface) Serializable)。如果对象的对象数据成员不可序列化,则必须将其标记为 transient :
private transient SomeClass notSerializable;
关于序列化不可序列化成员的编辑
这取决于您尝试序列化的不可序列化的内容。因为这是一个用 Android 标记的问题,所以它可以是一个 Context 对象。
上下文不可序列化是有原因的,它们与应用程序或 Activity 的生命周期相关联。它的状态是易变的,即使您稍后可以对其进行序列化和反序列化,它的内部状态也没有意义,因为已经建立了一个新的上下文,一个新的线程甚至一个不同的进程现在可能正在运行。
对于像 Contexts 这样的数据成员,您需要将它们声明为 transient 的,并将最新且有效的当前 Context 重新分配给反序列化的对象。
如果您正在尝试序列化不同类型的对象,这些对象一方面仅表示数据,例如一堆字符串和/或数字,但另一方面不可序列化,您有两个选择:
- 如果这些是您的类,则只需向它们添加 Serializable 接口(interface)
- 或者您可以在具有不可序列化数据成员的类中自定义序列化过程
自定义可以通过实现方法来完成
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
这些方法在类的序列化/反序列化时被调用。诀窍是获取不可序列化对象的数据/状态,并将该数据打包到可序列化对象中。例如,您可以使用任何 Collection 对象(如 ArrayList)来顺序存储原始数据。
假设您想要序列化一个 Location 对象(用于地理位置坐标),并且我们还假设该对象不可序列化。但是你知道它由三个可以序列化的值组成:
- 双经度
- 双纬度
- 双高度
- (以及供应商、速度、时间等其他因素...)
您可以将这三个值存储在 ArrayList 中,或者您可以创建您自己的自定义可序列化类来存储这些值以用于序列化目的。 将 ArrayList 或可序列化的中间对象放入自定义 writeObject 方法的 ObjectOutputStream 中。
在 readObject 中,您需要反转这些步骤并根据序列化的原始数据重建不可序列化的数据成员。
我还建议阅读 Sun 的 documentation about serialization
关于android - 某些对象不保存到 Android 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11416650/