Reputation: 1047
I have the following class:
public class DetailedProduct implements Serializable {
//attributes + get and set
private Colour colour;
//get+set
public class Colour implements Serializable{
private ArrayList<Image> images;
//get+set
public Image[] getImages() {
return images.toArray(new Image[images.size()]);
}
}
public class Image implements Serializable{
private static final long serialVersionUID = 3460333138445770749L;
private String image1;
private String image2;
private String image3;
//get/set methods
}
}
I created afterwards an Intent as following
DetailedProduct.Colour mCurrentColour;
Intent myIntent = new Intent(DetailsActivity.this, ImageGallery.class);
myIntent.putExtra("Images", mCurrentColour.getImages());
startActivity(myIntent);
In the ImageGallery class now I tried the following code:
Serializable extras = getIntent().getSerializableExtra("Images");
if (extras != null) {
images = (Image[]) extras;
}
But I'm taking the following exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com./com.productdetails.ProductImageGallery}: java.lang.ClassCastException: java.lang.Object[] cannot be cast to com.productdetails.DetailedProduct$Image[]
How can I cast correctly the serializable to an array of Image
Upvotes: 2
Views: 378
Reputation: 20885
The Android runtime fails to serialize the array. The array type still implements Serializable
, but when it comes back from the Bundle used by the Intent, it has lost all of its information (including type, which is always Ljava.lang.Object
. Some answers on the internet suggest using Parcelable
, however I tried and did not succeded myself.
What can be accomplished is transmitting a collection of Parcelable
objects, but in the form of an ArrayList
, which also happens to be the data structure you use in your original sample. The calling code looks like this:
Intent intent = new Intent(this, Target.class);
ArrayList<Foo> data = new ArrayList<Foo>();
data.add(new Foo());
intent.putParcelableArrayListExtra("data", data);
intent.putExtra("serializable", new Foo[] {new Foo()});
startActivity(intent);
I employed the usual dummy class named Foo
, but note that implementing Parcelable
is quite tedious. Moreover, it requires your class to have a static
field named CREATOR
of type Parcelable.Creator<T>
, and with inner types this is not possible at all in the Java language. That's why you'll have to switch to nested (static) classes, eventually passing your current outer instance in the constructor and changing fields visibilty accordingly (from private
to public
or package-private). By the way, this will also improve testability of your codebase, because you reduce coupling. What I mean is, instead of this uncompilable source:
public class Product implements Parcelable {
public class Color implements Parcelable {
public static final Parcelable.Creator<Color> CREATOR; // Illegal!!!
}
}
something like this
public class Product implements Parcelable{
public static class Color implements Parcelable {
public Color(Product exOuter) {
}
}
}
but note that this way you won't be able to access non-static members of the enclosing class, thus it may be better to move Color
out of Product
.
Upvotes: 0
Reputation: 11310
You cast is not correct
java.lang.ClassCastException: java.lang.Object[] cannot be cast to com.productdetails.DetailedProduct$Image[]
You give a ListArray to intent and you try to cast it with array
this line are not correct
if (extras != null) {
images = (Image[]) extras;
}
replace with
if (extras != null) {
images = (ListArray<Image>) extras;
}
Upvotes: 0
Reputation: 141
You passed the images as an arrayList. But you are taking it as an array..
Use the following code
Serializable extras = getIntent().getSerializableExtra("Images");
if (extras != null) {
images = (ArrayList<Image>) extras;
}
Upvotes: 0
Reputation: 1174
From quick thought, you can simply make the images into bytearray[], and since bite arrays primitive types which is serializable.
Upvotes: 0