In the generated writeToParcel method, null values are serialized as 1, non null as 0 :
if (getValue() == null) {
dest.writeInt(1);
} else {
dest.writeInt(0);
dest.writeString(getValue());
}
This cause issues when this parcelable is exchanged between applications with different versions of the object. For example :
v1 lib have :
@AutoValue
public abstract class MyObject implements Parcelable {
@Nullable public abstract String getName();
@Nullable public abstract Integer getValue();
}
At some point we added some new fields to this object to create a v2 version of our lib :
@AutoValue
public abstract class MyObject implements Parcelable {
@Nullable public abstract String getName();
@Nullable public abstract Integer getValue();
@Nullable public abstract String getSurname();
@Nullable public abstract Integer getNewValue();
}
An application using v1 should still be able to send the object to an application using v2, with null value for the new fields. But with the existing implementation, the generated createFromParcel method will be :
return new AutoValue_MyObject(
in.readInt() == 0 ? in.readString() : null,
in.readInt() == 0 ? in.readInt() : null,
in.readInt() == 0 ? in.readString() : null,
in.readInt() == 0 ? in.readInt() : null
)
The first two fields are deserialized properly, but since the buffer is empty after this, readInt will always return 0, meaning that the object is not null. The second readString() will return null so the value for the second string is null as expected, but the second Integer value is 0 instead of null (same issue should happen with classes that wrap primitive types).
This behavior would not happen by inverting 0 and 1 for null/non null. Is there a reason why 0 is used for non null instead of null ?
Also changing this behavior now could result in many more backward compatibility breaks for application that used a previous version of auto-value-parcel.
In the generated writeToParcel method, null values are serialized as 1, non null as 0 :
This cause issues when this parcelable is exchanged between applications with different versions of the object. For example :
v1 lib have :
At some point we added some new fields to this object to create a v2 version of our lib :
An application using v1 should still be able to send the object to an application using v2, with null value for the new fields. But with the existing implementation, the generated createFromParcel method will be :
The first two fields are deserialized properly, but since the buffer is empty after this, readInt will always return 0, meaning that the object is not null. The second readString() will return null so the value for the second string is null as expected, but the second Integer value is 0 instead of null (same issue should happen with classes that wrap primitive types).
This behavior would not happen by inverting 0 and 1 for null/non null. Is there a reason why 0 is used for non null instead of null ?
Also changing this behavior now could result in many more backward compatibility breaks for application that used a previous version of auto-value-parcel.