Android日历序列化与Java 6不兼容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android日历序列化与Java 6不兼容相关的知识,希望对你有一定的参考价值。

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

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

Android客户端:(我创建了一个空白项目,并为清单添加了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 Server,然后在android模拟器中运行Android Client,则应该收到错误。

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

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

答案

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

这不太可能奏效。

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

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

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

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

要么将值传递为longgetTimeInMillis()),要么编写自己的JSON / XML / protobuf /无论是哪个序列化程序。

另一答案

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

因此,我认为那些在Android上工作的人甚至都不愿意改变常见类的serialVersionUID。序列化兼容性是将类从一个JDK版本发展到另一个版本时最明智的问题之一,想象一下维护JavaSE和Android之间的序列化兼容性是头疼的问题。

以上是关于Android日历序列化与Java 6不兼容的主要内容,如果未能解决你的问题,请参考以下文章

android 设置系统闹钟和系统日历提醒

日历热图:颜色与指定不符

开发Android 日历教程

Java 设定工作日日历

AGP 3.5是否与Gradle 6兼容?

Android 中的日历视图