我需要序列化GeoPoints列表然后再读回来。我搜索了网络,发现我可以实现自己的GeoPoint并实现可序列化。它可以工作,我可以将对象写入.ser文件但是当我读回来时,我得到一个invalidclassexception,它继续说明详细信息 - 对原始GeoPoint对象的非法感知。我假设我没有正确扩展MyGeoPoint类中的GeoPoint。有人可以看看并告诉我我在哪里犯错误吗?
import com.google.android.maps.GeoPoint;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class MyGeoPoint extends GeoPoint implements Serializable {
static final long serialVersionUID = -3010695769693014199L;
public MyGeoPoint(int latitude, int longitude){
super(latitude, longitude);
}
public MyGeoPoint(){
this(0,0);
}
private void writeObject(ObjectOutputStream s) throws IOException{
s.defaultWriteObject();
}
private void readObject(ObjectInputStream s)
throws java.io.IOException, java.lang.ClassNotFoundException{
s.defaultReadObject();
}
}
然后像
一样使用它File filex = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +"floodData.ser");
MyGeoPoint aPoint = new MyGeoPoint();
MyGeoPoint readPoint = null;
//write
try{
FileOutputStream f = new FileOutputStream(filex);
ObjectOutputStream s = new ObjectOutputStream(f);
s.writeObject(aPoint);
s.close();
} catch (IOException e) {
e.printStackTrace();
}
//read
try {
FileInputStream ff = new FileInputStream(filex);
ObjectInputStream ss = new ObjectInputStream(ff);
readPoint = (MyGeoPoint)ss.readObject();
ss.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
//end serialisationtest
答案 0 :(得分:4)
问题是GeoPoint
没有no-arg构造函数,请参阅Serializable的JavaDoc:
的JavaDoc要允许序列化非序列化类的子类型, 子类型可能承担保存和恢复状态的责任 超类型的公共,受保护和(如果可访问)包 领域。只有在类中,子类型才可以承担此责任 它扩展了一个可访问的无参数构造函数来初始化 阶级的国家。如果这样,声明一个Serializable类是错误的 事实并非如此。将在运行时检测到错误。
序列化运行时检测到以下之一时抛出 一个班级的问题。
- 该类的串行版本与从流
读取的类描述符的版本不匹配- 该类包含未知数据类型
- 该类没有可访问的无参数构造函数
答案 1 :(得分:1)
您无需扩展com.google.android.maps.GeoPoint即可拥有可序列化的对象来存储您的纬度/经度坐标。
由于你不拥有原始对象,你不应该这样做,因为如果谷歌决定更改原始的GeoPoint,让我们说...添加/删除方法,更改方法签名等...你可能会进入的烦恼。
更糟糕的是,您的代码无法移植,Kindle Fire上的FYI Android无法访问Google Maps API,因此从com.google.android.maps.GeoPoint扩展的应用无效。< / p>
要做的是创建一个具有相同精确属性(及其类型)的Serializable POJO来存储您将序列化的纬度/经度坐标:
package com.yourapp.beans;
public class YourGeoPoint implements Serializable {
private static final long serialVersionUID = -99127398709809L;
private int latitudeE6;
private int longitudeE6;
public YourGeoPoint() {
this.setLatitudeE6(0);
this.setLongitudeE6(0);
}
public YourGeoPoint(int latitudeE6, int longitudeE6) {
this.setLatitudeE6(latitudeE6);
this.setLongitudeE6(longitudeE6);
}
public int getLatitudeE6() {
return latitudeE6;
}
public void setLatitudeE6(int latitudeE6) {
this.latitudeE6 = latitudeE6;
}
public int getLongitudeE6() {
return longitudeE6;
}
public void setLongitudeE6(int longitudeE6) {
this.longitudeE6 = longitudeE6;
}
}
然后,只要您需要com.google.android.maps.GeoPoint ...并在反序列化到您的GeoPoint实例后,只需执行以下操作:
import com.google.android.maps.GeoPoint;
import com.yourapp.beans.YourGeoPoint;
//...
YouGeoPoint yourGeoPoint = // De-serialization...
GeoPoint geoPoint = new GeoPoint(yourGeoPoint.getLatitudeE6(), yourGeoPoint.getLongitudeE6());
它可以100%运行,您的代码可以移植到没有Google Maps API的Android设备中...如果是这种情况,只需导入您有权访问的任何地图库(例如ESRI或OpenSignalMaps)并使用来自您自己的反序列化对象的坐标获取其中一个“GeoPoints”或等效对象。
干杯!
答案 2 :(得分:0)
为了使这个答案更加完整,我试图通过一个绑定修复解决问题。尝试将以下行添加到类writeObject和readObject ...
private void writeObject(ObjectOutputStream s) throws IOException{
s.writeInt(this.getLatitudeE6());
s.writeInt(this.getLongitudeE6());
}
private void readObject(ObjectInputStream s)
throws java.io.IOException, java.lang.ClassNotFoundException{
this(s.readInt(), s.readInt());
}
答案 3 :(得分:0)
更简洁的方法是将类设置器和getter更改为:
private double lat;
private double lng;
public LatLng getLocation() {
LatLng latLng = new LatLng(this.lat, this.lng);
return latLng;
}
public void setLocation(LatLng location) {
this.lat = location.latitude;
this.lng = location.longitude;
}