So, i have the following class, which i want to serialize using Android Parcelable
public class Parent{
public static final int x; //primtive type
public static final Animal y; //another percelable
public static final String z; //object type
public class Inner{
public static final int a; //primtive type
public static final Animal b; //another percelable
public static final String c; //object type
}
private int classIntState; //primtive type
private Animal classAnimalState; //another percelable
private String classObjectState; //object type
}
I know the drills for class variables. but having trouble with finals and finals from inner classes.
Done some additional research, and i looked into BlutoothDevice class, which happens to be also Parcelable and have bunch of constants.
And, i found this on source code,
public static final Parcelable.Creator<BluetoothDevice> CREATOR =
new Parcelable.Creator<BluetoothDevice>() {
public BluetoothDevice createFromParcel(Parcel in) {
return new BluetoothDevice(in.readString());
}
public BluetoothDevice[] newArray(int size) {
return new BluetoothDevice[size];
}
};
public void writeToParcel(Parcel out, int flags) {
out.writeString(mAddress);
}
BluetoothDevice(String address) {
getService(); // ensures sService is initialized [nothing to do with parcelable]
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
}
mAddress = address;
}
Seems like these guys are completely ignoring all those finals/Constants from their Parcelable implementation.
This puzzle me a bit, so looked into how Java Serialize finals and found this discussion on stack overflow. What i understood from their is , it is done by JVM using reflection. Then i looked into Parcel and Parcelable source and doesn't seems like anywhere finals are handles explicitly.
Do i have to, or i do not have to? What really am i missing here?
Seems like these guys are completely ignoring all those finals/Constants from their Parcelable implementation.
Well, if you look at the source for BluetoothDevice
, you'll notice that all of the final
variables are defined outside the constructor. So when return new BluetoothDevice(in.readString())
is called, all the final
variables outside the constructor definition are initialized to their respective values, and then the constructor BluetoothDevice(String address)
is called.
What I'm trying to say is that those values are not written or read from the Parcel
. They are simply initialized by the class right before the constructor is called by the CREATOR
of Parent
(although you haven't defined one in your question's Parent
source code).
Now, let's say you initialize the values of the final
variables based on the parameters in a parameterized constructor. For example,
public Parent(int x, Animal y, String z) {
this.x = x;
this.y = y;
this.z = z;
}
In THAT case you'll need to write x
, y
and z
to the Parcel
in writeToParcel()
just as you would any non-final
value.
Then in your Parent
class' CREATOR
:
public static final Parcelable.Creator<Parent> CREATOR =
new Parcelable.Creator<Parent>() {
public Parent createFromParcel(Parcel in) {
//read values from Parcel
int intParam = in.readInt();
Animal animalParam = in.readParcelable(Animal.class.getClassLoader());
String stringParam = in.readString();
//create parent
Parent parent = new Parent(intParam, animalParam, stringParam);
return parent;
}
public Parent[] newArray(int size) {
return new Parent[size];
}
};
That is, you read the values of the variables, and then use the constructor to assign them. Again, this is pretty much almost the same as if the variables weren't final
. I don't think it makes any difference that they are.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.