某些对象不保存到Android内存

时间:2012-07-10 15:23:13

标签: android object save

我正在使用以下代码来保存和检索Androids内部存储器中的对象。我用一个字符串对象测试了它成功了。当我尝试保存位图时,我得到一个IOException。 (我发现我必须调用compress方法)所以我注意到我可以保存一些对象,保存对象的限制是什么?

当我保存对象时,它是否只保存字段?我可以保存包含其他对象的对象吗?请把我弄清楚。

代码:

    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);

        }

    }

提前致谢。

3 个答案:

答案 0 :(得分:1)

限制是所有对象都必须是可序列化的(实现Serializable接口)。如果对象的对象数据成员不可序列化,则必须将其标记为瞬态:

private transient SomeClass notSerializable;

关于序列化非可序列化成员的编辑

这取决于您尝试序列化的不可序列化的内容。由于这是一个用Android标记的问题,因此它可能是一个Context对象。

上下文不是可序列化的,因为它们与应用程序或活动的生命周期相关联。它的状态是易变的,即使你以后可以对其进行序列化和反序列化,它的内部状态也没有意义,因为新的Context已经建立,新的线程甚至是一个不同的进程可能正在运行。

如果像上下文这样的数据成员,您需要将它们声明为瞬态,并将新的有效当前上下文重新分配给反序列化的对象。

如果您尝试序列化不同类型的对象,一方面只是表示数据,如一串字符串和/或数字,但另一方面不可序列化,您有两种选择:

  • 如果这些是您的类,那么只需将Serializable接口添加到它们
  • 即可
  • 或者您可以在类中自定义具有不可序列化数据成员的序列化过程

可以通过实施方法

来完成定制
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

答案 1 :(得分:0)

是的,您可以将所有类型的数据保存在对象中,您只需要确保定义对象中的所有变量:

public class YourObject{
int yourInteger;
String yourString;
Bitmap yourBitmap;
float yourFloat;
...
}

您还需要确保使用set方法设置这些对象的字段:

public class YourObject{
int yourInteger;
String yourString;
Bitmap yourBitmap;
float yourFloat;
...
//sets the value of yourInt
public void setYourInteger(int yourInt){
 this.yourInt = yourInt;

}

}

如果您没有明确设置字段,则无法保存它们。

答案 2 :(得分:0)

来自Oracle的Javadoc:

  

ObjectOutputStream写入原始数据类型和图形   Java对象到底层的OutputStream。对象和其他数据   然后可以使用ObjectInputStream读取(重构)。   可以使用文件来完成对象的持久存储   流。如果流是网络套接字流,则对象可以   可以在其他主机或其他过程中重组。

     

仅支持java.io.Serializable或的对象   java.io.Externalizable接口可以序列化为输出   流。每个可序列化对象的类都被编码,包括   类的类名和签名,对象的值   非静态和非瞬态字段和数组,包括任何   对象引用的其他对象(除了那些对象)   实现java.io.Serializable接口本身)。多   使用引用共享对对同一对象的引用进行编码   机制,以便可以恢复对象的图形   适当。

     

对象的默认序列化机制会写入类   对象,类签名和所有非瞬态的值   和非静态字段。对其他对象的引用(除了   瞬态或静态字段)也会导致写入这些对象。