【问题标题】:Android Calendar Serialization Incompatible with Java 6Android 日历序列化与 Java 6 不兼容
【发布时间】:2023-04-02 18:40:02
【问题描述】:

我正在尝试在 Java 服务器和 Android 客户端之间使用对象序列化套接字连接。尝试通过此连接发送日历对象时遇到问题。

Calendar 对象由 Java 服务器发送并由 Android 客户端接收,但我在 LogCat 中收到错误消息:

java.lang.NullPointerException: java.util.TimeZone 类型的预期接收者,但得到了 null

我意识到它没有正确反序列化。

我准备了这个代码示例来重现错误:

Java 服务器:

public class SerializeTest {

    public static void main(String[] args) {
        try {

        ServerSocket serverSocket = new ServerSocket(49100);
        Socket socket = serverSocket.accept();
        OutputStream oStream = socket.getOutputStream();
        ObjectOutputStream ooStream = new ObjectOutputStream(oStream);

        String testString = "This is a test String";
        Calendar testCalendar = Calendar.getInstance();

        ooStream.writeObject(testCalendar);
        ooStream.reset();
        ooStream.close();

        } catch(Exception e){
            e.printStackTrace();
        }
    }
}

安卓客户端: (我创建了一个空白项目并在清单中添加了 Internet 权限)

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket("10.0.2.2", 49100);
                    InputStream iStream = socket.getInputStream();
                    ObjectInputStream oiStream = new ObjectInputStream(iStream);

                    Object object = oiStream.readObject();
                    Log.d("Test", object.toString());
                    oiStream.close();

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

}

使用该代码示例,如果您启动 Java 服务器,然后在 android 模拟器中运行 Android 客户端,您应该会收到错误消息。

我注意到 android-17/android.jar 中的 java.util.Calendar 对象与 jre6 中的 java.util.Calendar 对象不同。但是,它们都共享相同的 serialVersionUID 1807547505821590642L。 (这告诉我它们应该通过序列化来兼容)。

所以我想我正在寻找这里发生的事情的解释,我想知道,我可以在 Java 和 Android 上使用其中一个日历对象吗? (如果是,怎么做?)我应该使用其他对象吗?

【问题讨论】:

  • 我也有同样的问题。你找到解决办法了吗?
  • 我最终使用 JSON 而不是对象序列化。我使用 gson (code.google.com/p/google-gson) 来帮助对其进行足够的抽象,使其与使用对象序列化一样简单透明。

标签: java android sockets serialization calendar


【解决方案1】:

我正在尝试在 Java 服务器和 Android 客户端之间使用对象序列化套接字连接

这不太可能奏效。

我意识到它没有正确反序列化。

这是一个很好的例子,说明它不太可能很好地工作。 Android 致力于维护二进制 API 的兼容性。任何类的内部实现都会被修改,这意味着Java风格的对象序列化会被修改。

我可以在 Java 和 Android 上使用其中一个日历对象吗?

当然。只是不要在不同平台之间使用 Java 风格的对象序列化。

要么将值作为long (getTimeInMillis()) 传递,要么编写自己的 JSON/XML/protobuf/whatever 序列化程序。

【讨论】:

    【解决方案2】:

    JavaSE 版本和 Android 版本之间没有一对一的映射关系。 Android 和 Java 的发展方式不同。请参阅这些 SO 问题:

    因此,我认为在 Android 上工作的人甚至都懒得更改公共类的serialVersionUID。在将类从一个 JDK 版本升级到另一个版本时,序列化兼容性是最明智的问题之一,想象一下保持 JavaSE 和 Android 之间的序列化兼容性会令人头疼。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 2015-09-20
      相关资源
      最近更新 更多