一身转战三千里,一剑曾当百万师。这篇文章主要讲述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日历序列化与Java 6不兼容】这不太可能奏效。
我意识到它没有正确地反序列化。这是一个很好的例子,说明为什么它不太可能运作良好。 Android致力于维护二进制API兼容性。任何类的内部实现都需要修改,这意味着Java样式的对象序列化可能会被修改。
我可以在Java和Android上使用其中一个日历对象吗?当然。只是不要在不同的平台之间使用Java风格的对象序列化。
要么将值传递为
long
(getTimeInMillis()
),要么编写自己的JSON / XML / protobuf /无论是哪个序列化程序。另一答案JavaSE版本和Android版本之间没有一对一的映射。 Android和Java的发展方式不同。看到这些SO问题:
- How does Android's Java version relate to a Java SE version?
- JRE on Android
serialVersionUID
。序列化兼容性是将类从一个JDK版本发展到另一个版本时最明智的问题之一,想象一下维护JavaSE和Android之间的序列化兼容性是头疼的问题。推荐阅读
- 在Android中,每天在特定时间设置重复警报
- 解决方案(从C#app调用Crystal Report导致“数据库登录失败”或“加载报告失败”)
- Jackson ObjectMapper给出了递归数据类型的错误
- Android java测试浮动负值和正值不起作用吗()
- Settings.Secure.ANDROID_ID在构建APK和签名APK中为何不同()
- Struts 2 - 没有映射名称空间[/]的动作和与上下文路径[/ LoginApplication]相关联的动作名称[validateLogin]
- ActionMapper类在struts 2中的作用是什么
- 执行新的runnables时丢失ApplicationContext
- 在Winforms中使用带有C#的InputSimulator以正确的方式模拟按键