某些对象不会保存到 Android 内存中 [英] Some object don't save to Android internal memory

查看:50
本文介绍了某些对象不会保存到 Android 内存中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码在 Android 内部存储器中保存和检索对象.我已经成功地使用字符串对象对其进行了测试.当我尝试保存位图时,出现 IOException.(我发现我要调用compress方法)所以我注意到我可以保存一些对象,保存对象有什么限制?

I'm using the following code to save and retrieve objects to and from the Androids internal memory. I have tested it with a string object with success. When I try to save a Bitmap I get a IOException. (I found out that I have to call the compress method) So I notice that I can save some objects, what are the restrictions to saving objects?

当我保存一个对象时,它是否只保存字段?我可以保存包含其他对象的对象吗?请清理我.

When I save a object, does it only save the fields? Can I save objects that contains other objects? Please clear me up.

代码:

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

        }

    }

提前致谢.

推荐答案

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

The restriction is that all objects have to be serializable (implement the interface Serializable). If an object data member of an object is not serializable, it has to be marked as transient:

private transient SomeClass notSerializable;

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

EDIT about serializing non-serializable members

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

It depends on what you are trying to serialize that is not serializable. Since this is a question tagged with Android it could be a Context object for example.

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

Contexts are not serializable for a good reason, they are tied to a life cycle, either of the application or of an Activity. Its state is volatile and even if you could serialize and deserialize it later, its internal state wouldn't make sense, since a new Context has been established, a new thread or even a different process may be running by now.

对于像 Contexts 这样的数据成员,您需要将它们声明为瞬态,并将新鲜有效的当前 Context 重新分配给反序列化的对象.

In case of data members like Contexts you need to declare them as transient and re-assign the fresh and valid current Context to the deserialized object.

如果您尝试序列化不同类型的对象,这些对象一方面仅表示像一堆字符串和/或数字这样的数据,但另一方面又不可序列化,您有两个选择:

If you are trying to serialize different kinds of objects that on the one hand just represent data like a bunch of strings and / or numbers, but on the other hand are not serializable, you have two options:

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

自定义可以通过实现方法来完成

Customization can be done by implementing the methods

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

在类的序列化/反序列化时调用这些方法.诀窍是获取不可序列化对象的数据/状态并将该数据打包到可序列化对象中.例如,您可以使用任何 Collection 对象(如 ArrayList)来顺序存储原始数据.

These methods are invoked on serialization / deserialization of the class. The trick is to take the data / state of a non-serializable object and pack that data into a serializable object instead. You could for example use any Collection object like an ArrayList for sequentially storing the raw data.

假设您要序列化 ​​Location 对象(用于地理位置坐标),并且假设该对象不可序列化.但是你知道它由三个可以序列化的值组成:

Let's assume you want to serialize a Location object (for geo location coordinates) and let's also assume that object is not serializable. But you know that it consists of three values which can be serialized:

  • 双经
  • 双纬度
  • 双重高度
  • (以及其他,如提供商、速度、时间...)

您可以将这三个值存储在一个 ArrayList 中,或者您可以创建自己的自定义、可序列化类来存储这些值以用于序列化目的.将 ArrayList 或可序列化的中间对象放入自定义 writeObject 方法的 ObjectOutputStream.

You could store these three values in an ArrayList or you could create your own custom, serializable class which stores these values for serialization purposes. Put the ArrayList or your serializable intermediate object into the ObjectOutputStream of your custom writeObject method.

在 readObject 中,您需要颠倒这些步骤并根据您序列化的原始数据重建不可序列化的数据成员.

In readObject you need to reverse these steps and reconstruct your data member that is not serializable based on the raw data you serialized.

我还建议阅读 Sun 的关于序列化的文档

I also suggest reading Sun's documentation about serialization

这篇关于某些对象不会保存到 Android 内存中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆