Как сериализовать сторонний несериализуемый конечный класс (например, google LatLng class)?

Я использую класс Google LatLng из v2 Google Play Services. Этот конкретный класс является окончательным и не реализует java.io.Serializable. Можно ли каким-либо образом реализовать этот класс LatLng класса Serializable?

public class MyDummyClass implements java.io.Serializable {
    private com.google.android.gms.maps.model.LatLng mLocation;

    // ...
}

Я не хочу объявлять mLocation переходный.

Ответ 1

Это не Serializable, но это Parcelable, если бы это был вариант. Если бы вы не справились с сериализацией самостоятельно:

public class MyDummyClass implements java.io.Serialiazable {
    // mark it transient so defaultReadObject()/defaultWriteObject() ignore it
    private transient com.google.android.gms.maps.model.LatLng mLocation;

    // ...

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeDouble(mLocation.latitude);
        out.writeDouble(mLocation.longitude);
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        mLocation = new LatLng(in.readDouble(), in.readDouble());
    }
}

Ответ 2

Вы можете посмотреть ObjectOutputStream.

Сначала вам нужно создать замену для вашего объекта:

    public class SerializableLatLng implements Serializable {

    //use whatever you need from LatLng

    public SerializableLatLng(LatLng latLng) {
        //construct your object from base class
    }   

    //this is where the translation happens
    private Object readResolve() throws ObjectStreamException {
        return new LatLng(...);
    }

}

Затем создайте соответствующий ObjectOutputStream

public class SerializableLatLngOutputStream extends ObjectOutputStream {

    public SerializableLatLngOutputStream(OutputStream out) throws IOException {
        super(out);
        enableReplaceObject(true);
    }

    protected SerializableLatLngOutputStream() throws IOException, SecurityException {
        super();
        enableReplaceObject(true);
    }

    @Override
    protected Object replaceObject(Object obj) throws IOException {
        if (obj instanceof LatLng) {
            return new SerializableLatLng((LatLng) obj);
        } else return super.replaceObject(obj);
    }

}

Затем вам придется использовать эти потоки при сериализации

private static byte[] serialize(Object o) throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new SerializableLatLngOutputStream(baos); 
    oos.writeObject(o);
    oos.flush();
    oos.close();
    return baos.toByteArray();
}