【问题标题】:Serializable Errors with Java ObjectJava 对象的可序列化错误
【发布时间】:2013-09-17 00:50:39
【问题描述】:

编辑,这是我使用 cmets 解决的方法 所以在尝试了不同的序列化方式并查看了我的代码之后,我终于发现渲染器中绘制的每个对象都包含 FloatBuffers。感谢 Ted Hopp,我创建了一个胶囊课程。然后我尝试使用 .array() 返回 FloatBuffers 的浮点表示,这是您无法做到的。我的猜测是因为这些是在线程上运行的。因此,使用 Learn OpenGL ES 的建议来使用 get,我改为使用了

public float[] getVertexBuffer()
{
    float[] local = new float[vertexBuffer.capacity()];
    vertexBuffer.get(local);
    return local;
}

哪个有效并返回 float[]。

然后我将它们全部存储在我创建的每个 mGrid 对象的胶囊对象中

        Encapsulate capsule = new Encapsulate(values);
        for(int i = 0; i < values[0]; i++)
        {
            for(int j = 0; j < values[1]; j++)
            {
                capsule.storeVertex(i,j,mRenderer.mGrid[i*values[1] + j].getVertexBuffer());
                capsule.storeColors(i,j,mRenderer.mGrid[i*values[1] + j].getmColors());
                capsule.storePillar(i,j,mRenderer.mGrid[i*values[1] + j].getPillarPositions());
            }
        }

然后我可以最终保存它,因为它是可序列化的。谢谢大家

问题描述 所以我试图保存一个 GLSurfaceView 对象,其类表示为

class GLWorld extends GLSurfaceView implements Serializable

现在我确定我正确地保存了。

public void saveSimulation()
{
    String fileName = "Test Save";
    try {
        FileOutputStream fos = openFileOutput(fileName, Context.MODE_PRIVATE);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(mGLView);
        Log.d("Save","Successfully Written");
        oos.close();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.d("Save","File not found exception");
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        Log.d("Save","IO exception");
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    finish();
}

但我遇到了一个错误,我不知道如何解决。我花了几个小时环顾四周,但没有找到类似的东西。

09-16 17:36:50.639: W/System.err(2996): java.io.NotSerializableException: java.nio.FloatToByteBufferAdapter

还有更多的系统错误行,我相信这源于这个错误。

我的 GLWorld 在其中创建了一个渲染器对象,该对象具有不同的对象,其中包含存储顶点和颜色数据的浮动缓冲区。我不知道该怎么做才能克服这个错误,或者为什么那些浮动缓冲区会抛出错误。除了实际尝试保存这个 GLWorld 对象之外,一切都运行得很顺利,这让我发疯了。

【问题讨论】:

  • 很高兴看到它现在可以工作了。 :) 对于未来的读者: 1) FloatBuffer.array() 是可选的,因此它仅在 FloatBuffer 由 Java 数组直接支持时才有效。在这种情况下,它是使用 allocateDirect() 创建的,因此后备内存存储位于本机堆中,这就是我们需要调用 .get() 的原因。 2)在线程之间访问数据时必须小心。 GLSurfaceView.queueEvent() 可用于将调用分派给 GL 线程,以便只有 GL 线程与缓冲区发生冲突。

标签: java android serialization opengl-es-2.0


【解决方案1】:

仅仅声明一个类implements Serializable 不足以成功序列化该类的对象。默认实现要求类的每个字段都是可序列化的。在您的情况下,有一个类型为 FloatToByteBufferAdapter 的字段不可序列化(可能还有更多)。

您可以定义自己的序列化机制来仅序列化您需要的内容。详情请见Serializable docs。请注意,通过子类化GLSurfaceView,即使您编写了正确的支持方法,您也不太可能成功反序列化此类。一方面,GLSurfaceView 没有默认(无参数)构造函数,这是 Java 序列化机制的要求。此外,许多对象根本无法序列化(例如流)。

我建议您将要序列化的数据封装在一个帮助类中,并将序列化/反序列化限制为这些数据。

【讨论】:

  • 如果封装,保存。稍后当我加载该对象时,我是否仍然拥有我保存的完全相同的渲染世界。还是会自行重置?因为我真正想要保存的是我创建的渲染器。因为如果是这样的话,我可以将渲染器保存在 GLWorld 类中的方法中
  • 我认为这个答案已经足够完整,我真的没有太多要补充的。 Ion,也许您可​​以做的只是将所有用户状态封装到普通的 Java 对象中,然后将它们序列化。当您想恢复状态时,只需重新创建 GLSurfaceView,然后恢复您需要的状态即可。
  • @Ion - 如果你可以让你的渲染器实现Serializable,我想你可以做你想做的。这取决于您的渲染器实现包含哪些数据。你显然不会得到相同的对象,但你可能并不真的想要那个;每当 EGL 上下文丢失并重新创建时,渲染器都需要重新初始化所有 OpenGL 资源。
  • 真正我想要保存的肉是我的 onDrawFrame(...) PASTEBIN LINK 中的这一部分。但由于 mGrid 只是一个被操纵的变量。如果我尝试保存 mGrid,我是否必须再次通过该 for 循环来重新创建所有内容。因此实际上没有保存其中的任何值。 (您看到的值的随机化非常重要,之后每个值都将变得更加不同和独特)。我可以将该 mGrid 转换为数组,然后存储该数组吗?那么我认为每个元素都会被保留。
  • @Ion - 没错。如果GridSquare 中的每个字段都是隐式可序列化的,或者是(正确)实现Serializable 的对象,那么您可以简单地声明GridSquare implements Serializable 并将其保存/恢复到对象流。
【解决方案2】:

必须假设 mGLView 继承中的某些内容包含不可序列化的 FloatTOByteBufferAdapter。

【讨论】:

  • 这提供了关于在哪里查看的建议,但并不是一个完整的答案。这将更适合作为对主要问题的评论。
  • 本来应该是,我以为我点击了评论添加评论:)
猜你喜欢
  • 2014-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多