Reputation: 15689
I recently came across a very stupid (at least from my point of view) implementation inside Androids Parcel
class.
Suppose I have a simple class like this
class Foo implements Parcelable{
private String[] bars;
//other members
public in describeContents(){
return 0;
}
public void writeToParcel(Parcel dest, int flags){
dest.writeStringArray(bars);
//parcel others
}
private Foo(Parcel source){
source.readStringArray(bars);
//unparcel other members
}
public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>(){
public Foo createFromParcel(Parcel source){
return new Foo(source);
}
public Foo[] newArray(int size){
return new Foo[size];
}
};
}
Now, if I want to Parcel a Foo
Object and bars
is null I see no way to recover from this situation (exept of catching Exceptions of course). Here is the implementation of these two methods from Parcel:
public final void writeStringArray(String[] val) {
if (val != null) {
int N = val.length;
writeInt(N);
for (int i=0; i<N; i++) {
writeString(val[i]);
}
} else {
writeInt(-1);
}
}
public final void readStringArray(String[] val) {
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
val[i] = readString();
}
} else {
throw new RuntimeException("bad array lengths");
}
}
So writeStringArray is fine if I pass bars
which are null. It just writes -1
to the Parcel. But How is the method readStringArray supposed to get used? If I pass bars
inside (which of course is null) I will get a NullPointerException from val.length
. If I create bars
before like say bars = new String[???]
I don't get any clue how big it should be. If the size doesn't match what was written inside I recieve a RuntimeException.
Why is readStringArray
not aware of a result of -1
which gets written on null objects from writeStringArray
and just returns?
The only way I see is to save the size of bars
before I call writeStringArray(String[])
which makes this method kind of useless. It will also redundatly save the size of the Array twice (one time for me to remember, the second time from writeStringArray
).
Does anyone know how these two methods are supposed to be used, as there is NO java-doc for them on top?
Upvotes: 11
Views: 10463
Reputation: 3938
It's not really clear from the (lack of) documentation but readStringArray()
is to be used when the object already knows how to create the string array before calling this function; for example when it's statistically instanciated or it's size is known from another previously read value.
What you need here is to call the function createStringArray()
instead.
Upvotes: 5
Reputation: 30874
You should use Parcel.createStringArray()
in your case.
I can't imagine a proper use-case for Parcel.readStringArray(String[] val)
but in order to use it you have to know the exact size of array and manually allocate it.
Upvotes: 34