Okay, so I have a class SomeClass
that is Parcelable
.
It has an array of another Parcelable
class called SuperClass
. In my constructor for SomeClass
, I'm trying to read the array of the SuperClass
objects into the myArray
instance variable. This would be straightforward; however:
SuperClass
has two subclasses FirstSubClass
and SecondSubClass
. The array temp
is supposed to have a mixture of all 3, but for some reason it has only SuperClass
objects (the if
and else if
statements don't seem to execute since none of the elements of temp
are instances of the subclasses).
public SomeClass(Parcel in) {
myArray = new SuperClass[100];
// this is probably where the problem is due to the classloader parameter:
Object[] temp = in.readArray(SuperClass.class.getClassLoader());
for(int i = 0; i < myArray.length; i++) {
if(temp[i] instanceof FirstSubClass)
myArray[i] = (FirstSubClass) temp[i];
else if(temp[i] instanceof SecondSubClass)
myArray[i] = (SecondSubClass) temp[i];
else
myArray[i] = (SuperClass) temp[i];
}
}
What I'm trying to figure out is how I can read the elements of an array of parcelable objects such that the subclasses of this object aren't automatically casted up to the superclass.
(I think I may have worded my question very confusingly, please tell me if I did).
I tried to reproduce your problem and I couldn't ... I used writeParcelableArray
and NOT writeTypedArray
. Here are the classes that I've create:
public class SuperClass implements Parcelable {
public static final Parcelable.Creator<SuperClass> CREATOR = new Creator<SuperClass>() {
@Override
public SuperClass[] newArray(int size) {
return new SuperClass[size];
}
@Override
public SuperClass createFromParcel(Parcel source) {
return new SuperClass(source);
}
};
private String label;
public SuperClass() {
}
protected SuperClass(Parcel source) {
label = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(label);
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
}
And its child classes:
public class FirstSubClass extends SuperClass {
public static final Parcelable.Creator<FirstSubClass> CREATOR = new Creator<FirstSubClass>() {
@Override
public FirstSubClass[] newArray(int size) {
return new FirstSubClass[size];
}
@Override
public FirstSubClass createFromParcel(Parcel source) {
return new FirstSubClass(source);
}
};
public FirstSubClass() {
super();
}
public FirstSubClass(Parcel source) {
super(source);
}
}
and:
public class SecondSubClass extends SuperClass {
public static final Parcelable.Creator<SecondSubClass> CREATOR = new Creator<SecondSubClass>() {
@Override
public SecondSubClass[] newArray(int size) {
return new SecondSubClass[size];
}
@Override
public SecondSubClass createFromParcel(Parcel source) {
return new SecondSubClass(source);
}
};
public SecondSubClass() {
super();
}
public SecondSubClass(Parcel source) {
super(source);
}
}
and the SomeClass
:
public class SomeClass implements Parcelable {
public static final Parcelable.Creator<SomeClass> CREATOR = new Creator<SomeClass>() {
@Override
public SomeClass[] newArray(int size) {
return new SomeClass[size];
}
@Override
public SomeClass createFromParcel(Parcel source) {
return new SomeClass(source);
}
};
private String name;
private SuperClass[] array;
public SomeClass(String name, SuperClass[] array) {
this.name = name;
this.array = array;
}
protected SomeClass(Parcel source) {
this.name = source.readString();
Parcelable[] temp = source.readParcelableArray(SuperClass.class.getClassLoader());
array = new SuperClass[temp.length];
for (int i = 0; i < temp.length; i++) {
array[i] = (SuperClass) temp[i];
}
}
public String toString() {
StringBuilder sb = new StringBuilder(name);
if (array == null || array.length == 0) {
sb.append(" Array is empty");
} else {
sb.append(" Array:");
for (SuperClass sc : array) {
sb.append(sc.getClass().getSimpleName());
sb.append(",");
}
sb.setLength(sb.length() - 1);
}
return sb.toString();
}
public String getName() {
return name;
}
public SuperClass[] getArray() {
return array;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeParcelableArray(array, flags);
}
@Override
public int describeContents() {
return 0;
}
}
From an activity I tap a button, create a SomeClass
object, attach to an intent that I start a new Activity and from there I log the passed value. The function that starts the activity:
@Override
public void onClick(View v) {
SuperClass[] array = new SuperClass[] { new SuperClass(), new FirstSubClass(), new SecondSubClass(), new SuperClass() };
SomeClass cl = new SomeClass("My Label", array);
Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("PASS", cl);
startActivity(intent);
}
and from NextActivity
:
public class NextActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set some content if you wish
Log.d("LOG_TAG", "Passed value: " + getIntent().getParcelableExtra("PASS"));
}
}
I can see in the logs:
Passed value: My Label Array:SuperClass,FirstSubClass,SecondSubClass,SuperClass
Exactly what I passed from previous activity ... Check the differences from your code, I suspect you didn't write a CREATOR
for FirstSubClass
and SecondSubClass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With