我正在尝试序列化我的位置类(使用android.location类)
但是,它给了我一个错误!
11-21 21:25:37.337: W/System.err(3152): java.io.NotSerializableException: android.location
所以,我试图扩展android.location.Location
类。
private class NewLocation extends Location implements Serializable {
private String Provider;
private double Latitude, Longitude, Altitude;
private float bear;
public NewLocation(Location l) {
super(l);
Provider = l.getProvider();
Latitude = l.getLatitude();
Longitude = l.getLongitude();
Altitude = l.getAltitude();
bear = l.getBearing();
}
}
之后,我尝试序列化扩展类,但同样的错误。
这是序列化代码
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutput oos = new ObjectOutputStream(bao);
byte[] data = null;
oos.writeObject(obj);
oos.flush();
oos.close();
data = bao.toByteArray();
return data;
}
为什么会出现这个错误?
答案 0 :(得分:11)
Android的Location
课程已经实施 Parcelable
。因此,您最好使用它而不是实现自己的序列化。
只需使用以下内容即可从bytes
获取Location
:
Parcel p = Parcel.obtain();
objLocation.writeToParcel(p, 0);
final byte[] b = p.marshall(); //now you've got bytes
p.recycle();
但是,您不应该从Parecelable
对象保存字节(在持久存储中)以供以后使用,因为它是专为高性能IPC传输而设计的,并不是通用的序列化机制。 / em>的
答案 1 :(得分:2)
只有实现Serializable接口,才能使不可序列化的类可序列化。 可序列化的类必须从可序列化的类继承(如果是继承的类),并且其所有属性都可以自行序列化。
可序列化类的所有子类型本身都是可序列化的。 http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
但是,如果你想序列化一个Parcelable类仍然可以,但肯定不是一个好习惯。
答案 2 :(得分:0)
我还需要将Location
与其大多数成员一起序列化,而不仅仅是纬度和经度。我最终写了自己的Serializable
类。源代码如下。用法是:
SerializableLocation serializable = new SerializableLocation(fromLocation);
Location toLocation = serializable.toLocation();
一些注意事项:
Location
的附加(Bundle
)未序列化Location
来自模拟提供商,还是丢失了。 Location.setIsFromMockProvider
只能由系统调用。这是源代码:
import android.location.Location;
import android.os.Build;
import androidx.annotation.NonNull;
import java.io.Serializable;
public class SerializableLocation implements Serializable {
private static final long serialVersionUID = 1L;
private static final int HAS_ALTITUDE_MASK = 1;
private static final int HAS_SPEED_MASK = 2;
private static final int HAS_BEARING_MASK = 4;
private static final int HAS_HORIZONTAL_ACCURACY_MASK = 8;
private static final int HAS_MOCK_PROVIDER_MASK = 16;
private static final int HAS_VERTICAL_ACCURACY_MASK = 32;
private static final int HAS_SPEED_ACCURACY_MASK = 64;
private static final int HAS_BEARING_ACCURACY_MASK = 128;
private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256;
private String provider;
private long time = 0;
private long elapsedRealtimeNanos = 0;
private double elapsedRealtimeUncertaintyNanos = 0.0f;
private double latitude = 0.0;
private double longitude = 0.0;
private double altitude = 0.0f;
private float speed = 0.0f;
private float bearing = 0.0f;
private float horizontalAccuracyMeters = 0.0f;
private float verticalAccuracyMeters = 0.0f;
private float speedAccuracyMetersPerSecond = 0.0f;
private float bearingAccuracyDegrees = 0.0f;
private int fieldsMask = 0;
// private Bundle extras = null;
private boolean hasElapsedRealtimeUncertaintyNanos() {
return (fieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
}
private boolean hasAltitude() {
return (fieldsMask & HAS_ALTITUDE_MASK) != 0;
}
private boolean hasSpeed() {
return (fieldsMask & HAS_SPEED_MASK) != 0;
}
private boolean hasBearing() {
return (fieldsMask & HAS_BEARING_MASK) != 0;
}
private boolean hasAccuracy() {
return (fieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0;
}
private boolean hasVerticalAccuracy() {
return (fieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0;
}
private boolean hasSpeedAccuracy() {
return (fieldsMask & HAS_SPEED_ACCURACY_MASK) != 0;
}
private boolean hasBearingAccuracy() {
return (fieldsMask & HAS_BEARING_ACCURACY_MASK) != 0;
}
private boolean isFromMockProvider() {
return (fieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
}
public SerializableLocation(@NonNull Location l) {
provider = l.getProvider();
time = l.getTime();
elapsedRealtimeNanos = l.getElapsedRealtimeNanos();
latitude = l.getLatitude();
longitude = l.getLongitude();
if (l.hasAltitude()) {
altitude = l.getAltitude();
fieldsMask |= HAS_ALTITUDE_MASK;
}
if (l.hasSpeed()) {
speed = l.getSpeed();
fieldsMask |= HAS_SPEED_MASK;
}
if (l.hasBearing()) {
bearing = l.getBearing();
fieldsMask |= HAS_BEARING_MASK;
}
if (l.hasAccuracy()) {
horizontalAccuracyMeters = l.getAccuracy();
fieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (l.hasVerticalAccuracy()) {
verticalAccuracyMeters = l.getVerticalAccuracyMeters();
fieldsMask |= HAS_VERTICAL_ACCURACY_MASK;
}
if (l.hasSpeedAccuracy()) {
speedAccuracyMetersPerSecond =
l.getSpeedAccuracyMetersPerSecond();
fieldsMask |= HAS_SPEED_ACCURACY_MASK;
}
if (l.hasBearingAccuracy()) {
bearingAccuracyDegrees = l.getBearingAccuracyDegrees();
fieldsMask |= HAS_BEARING_ACCURACY_MASK;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (l.hasElapsedRealtimeUncertaintyNanos()) {
elapsedRealtimeUncertaintyNanos =
l.getElapsedRealtimeUncertaintyNanos();
fieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
}
}
if (l.isFromMockProvider()) {
fieldsMask |= HAS_MOCK_PROVIDER_MASK;
}
}
public Location toLocation() {
Location l = new Location(provider);
l.setTime(time);
l.setElapsedRealtimeNanos(elapsedRealtimeNanos);
l.setLatitude(latitude);
l.setLongitude(longitude);
if (hasAltitude()) {
l.setAltitude(altitude);
}
if (hasSpeed()) {
l.setSpeed(speed);
}
if (hasBearing()) {
l.setBearing(bearing);
}
if (hasAccuracy()) {
l.setAccuracy(horizontalAccuracyMeters);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (hasVerticalAccuracy()) {
l.setVerticalAccuracyMeters(verticalAccuracyMeters);
}
if (hasSpeedAccuracy()) {
l.setSpeedAccuracyMetersPerSecond(speedAccuracyMetersPerSecond);
}
if (hasBearingAccuracy()) {
l.setBearingAccuracyDegrees(bearingAccuracyDegrees);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (hasElapsedRealtimeUncertaintyNanos()) {
l.setElapsedRealtimeUncertaintyNanos(
elapsedRealtimeUncertaintyNanos
);
}
}
// l.setIsFromMockProvider(isFromMockProvider());
return l;
}
}