GWT 和 Android 通信。枚举序列化问题

Posted

技术标签:

【中文标题】GWT 和 Android 通信。枚举序列化问题【英文标题】:GWT and Android communication. Enum serialization issue 【发布时间】:2013-09-27 11:55:27 【问题描述】:

我有一个运行良好的 GWT 应用程序。现在我正在尝试使用gwt-syncproxy 创建一个可以简单地重用服务器端代码的android客户端。

到目前为止,一切都运行良好。我能找到的唯一问题是当我启动 RPC 到一个需要枚举作为参数的方法时。

枚举看起来像这样:

import java.io.Serializable;
import com.google.gwt.user.client.rpc.IsSerializable;

public enum ReferenceTable implements IsSerializable, Serializable

    basetable, othertable;

    ReferenceTable()

我得到的错误信息是:

com.google.gwt.user.client.rcp.IncompatibleRemoteServiceException: Invalid type signature for package.ReferenceTable

这表明这是与序列化有关的问题。

我尝试使用IsSerializableSerializable 的不同组合,并且总是在部署之前清理项目。 GWT 应用程序和 Android 应用程序都对用于通信的数据类型使用相同代码。

有人知道如何解决这个问题吗?如果没有其他方法,我可以避免使用枚举,但我更喜欢使用它们。特别是,因为 GWT 服务器-客户端通信本身一切正常。


顺便说一句:服务器端的错误是:

Caused by: com.google.gwt.user.client.rpc.SerializationException: Invalid type signature for some.package.ReferenceTable
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.validateTypeVersions(ServerSerializationStreamReader.java:1116)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:610)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.readObject(ServerSerializationStreamReader.java:567)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader$ValueReader$8.readValue(ServerSerializationStreamReader.java:140)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:425)
    at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:312)
    ... 24 more

编辑

我创建了一个示例 GWT 应用程序和一个示例 Android 应用程序,因此人们可以实际尝试代码:

GWT part Android part

要部署应用程序,只需修改 build.properties 文件,然后将 build.xml 作为 ant 脚本运行。在Android应用的MainActivity中,修改URL指向GWT应用。

【问题讨论】:

您是否尝试向 ReferenceTable 类添加非参数构造函数? @ElHoss 请再次查看代码。有一个非参数构造函数。 ups ...你是对的。你的类在你的源包里吗? @ElHoss 是的,它在标记为源的shared 包中。 刚刚发现了一些东西:groups.google.com/forum/#!topic/google-web-toolkit/3MdEHteLw-4 【参考方案1】:

我无法按照描述验证您的问题(使用您提供的 src,它使用 JB 模拟器在我的开发环境中工作),尽管我在开发 Android 库期间看到了您指定的错误。我发现 GWT 中的许多“序列化”问题通常都很小,例如不可序列化的成员类型、缺少接口、默认构造函数等。由于您似乎已经解决了这些可能性,请验证以下内容:

您机器上的网络应用程序中使用的 GWT 版本。正在测试的 Android 操作系统版本(模拟器或设备)以及适用的设备。

虽然我不认为这会是个问题,但 Android 库是使用 GWT 2.5.0 src 编译的,因此如果服务器运行 GWT 不是 2.5.0,那么 RPC 可能(尚未经过测试的理论)因此,序列化失败。

这也可以解释为什么桌面客户端可以工作而 android 库不能。桌面客户端 syncproxy 库是针对 GWT 而不是 GWT 编译的,因此您在编译时链接您的 GWT 版本。 Android 库是使用 2.5.0 的 GWT src 代码直接编译的,并带有一些自定义覆盖,以减小库的大小,以便在 Dalvik 环境中使用和管理。

也就是说,如果您的项目可能,请尝试使用 GWT 2.5.0,清理/重新编译并试一试。如果没有,我的任务清单是让库升级到 2.5.1,但我还没有时间。

免责声明:我作为 gwt-syncproxy 项目的贡献者创建了有问题的 Android 库。我不能声称了解 GWT 或 syncproxy 内部的所有细节,但至少足以让库的工作模型发挥作用。我愿意接受有关改进库的建议,或者如果有任何 gwt-guru 存在,我们应该在内部解决这个问题的任何想法......

【讨论】:

太棒了,将示例应用程序切换到 GWT 2.5.0 就成功了。您能否估计一下何时可以将库更新到 2.5.1?如果您没有时间这样做,我可以将主应用程序切换到 2.5.0。但是,如果可能的话,我更愿意使用最新版本。如果您打算更新到 2.5.1,请告诉我! :) 这周我会看一下 2.5.1 的源代码,看看我能不能完成它。如果是这样,我将尝试在一周或两周内获得一个兼容 2.5.1 的库。如果文件发生重大更改,我可能需要更长的时间来过滤掉它以使其与 2.5.1 兼容(根据我的日程安排,一个月以上)。如果看起来要花那么长时间,我可能会推迟到 2.6 版本发布(预计 12 月初)。密切关注项目的 wiki 和问题跟踪器(我无法修改项目主页,因为我不是项目所有者,所有者是...MIA)。 太好了。我真的很期待这个!【参考方案2】:

删除 IsSerializable 接口声明,来自:

public enum ReferenceTable implements IsSerializable, Serializable

收件人:

public enum ReferenceTable implements Serializable

如果你的应用程序是纯粹的 GWT,你必须使用 IsSerializable 接口,但是,在这种情况下,你想在 Android 应用程序中使用相同的代码,你必须只使用 Serializable 接口。

【讨论】:

Enum 本身已经可以序列化,但它不起作用。添加Serializable 接口有什么帮助? 你是不是已经把IsSerializable接口删掉了,做个测试?这里的问题是 IsSerializable 接口是 GWT 独有的,当您尝试与其他平台(本例中为 Android)进行交互时,您必须声明 IsSerializable 接口,或者删除 GWT 代码中的引用。 是的,我已经尝试了所有组合。仅供参考,该应用程序(GWT 和 Android)适用于 IsSerializable,但不适用于枚举。 检查这个,可能有用:***.com/questions/17219111/… and ***.com/questions/4207988/problems-with-gwt-and-enum and ***.com/questions/8908352/… 不幸的是,我以前都阅读过它们,但没有一个包含解决我问题的方法。我不能强调这一点,因为实际的 GWT 应用程序正在运行,所以那里没有问题。这是 GWT 和 gwt-syncproxy 结合的具体问题。

以上是关于GWT 和 Android 通信。枚举序列化问题的主要内容,如果未能解决你的问题,请参考以下文章

尝试在枚举中添加 IsSerializable 时出现 gwt 错误

GWT JPA - 无法反序列化响应

GWT RPC 序列化和循环引用——先有鸡还是先有蛋的问题

gwt-syncproxy - WebProject 和 Android 应用程序之间的 RPC

Android 在没有 AppEngine 的情况下重用 GWT RPC 后端

将 Android 客户端添加到现有 GWT 服务器