Open WonderCsabo opened 7 years ago
What version are you using @WonderCsabo?
I forgot to mention that: 1.1.6
.
Hmm, looks like I need to lock down the implementations
field a bit more.
By default, Parceler doesn't perform a runtime class check on the contents of your list. It will treat it as the declared type.
There is a way around this, however. You could use a converter that uses the Parcels.wrap/unwrap to perform the runtime check. It is a bit slower, but probably not noticeable:
@Parcel
public class Zoo {
@ParcelPropertyConverter(ListParcelsWrapConverter.class)
List<Animal> animals;
@ParcelPropertyConverter(ListParcelsWrapConverter.class)
List<Tiger> tigers;
}
public class ListParcelsWrapConverter extends ArrayListParcelConverter<Object> {
@Override
public void itemToParcel(Object input, Parcel parcel) {
parcel.writeParcelable(Parcels.wrap(input), 0);
}
@Override
public Object itemFromParcel(Parcel parcel) {
return Parcels.unwrap(parcel.readParcelable(ListParcelsWrapConverter.class.getClassLoader()));
}
}
We touch on this in the docs: http://parceler.org/#polymorphism and http://parceler.org/#custom_serialization
I am always open to ideas here if you have a better technique or thoughts.
Ehh, i read README file, but i did not know you have a fancy webpage. Thanks!
This is an acceptable workaround, thanks! I am not sure if it is feasible, but i think a new annotation, or a parameter to @Parcel
would be uesful to mark the class as polymorphic. I think most users would want the concrete objects back.
Eh, i was too happy. This general class will not work.
I got this compilation error:
Zoo$$Parcelable.java
Error:(53, 107) error: incompatible types: List<Animal> cannot be converted to Collection<Object>
Error:(80, 119) error: incompatible types: ArrayList<Object> cannot be converted to List<Animal>
Zoo$$Parcelable.java
Error:(53, 109) error: incompatible types: List<Tiger> cannot be converted to Collection<Object>
Error:(80, 121) error: incompatible types: ArrayList<Object> cannot be converted to List<Tiger>
The obvious fix is changing to ListParcelsWrapConverter extends ArrayListParcelConverter<Animal>
. But i also have to create a different class for ListParcelsWrapConverter extends ArrayListParcelConverter<Tiger>
. 😢
Ugh, sorry, I was too quick in giving an example... yeah, you're right you'd have to create a different converter for each type. I need to fix the converter validation and casting to the given type.
Cool, I created the two classes. Actually I could create a generic base class which provides the method implementations, and the subclasses only differ in the class signature (generic argument). Maybe you can provide the base class in the library if it is a common problem.
One idea brought up before was to add an annotation property to trigger Parceler to use the Parcels.wrap/unwrap
for polymetric behavior instead of having to deal with a converter. Something like this:
@Parcel
public class Zoo {
@ParcelPropertyConverter(polymetric = true)
List<Animal> animals;
}
I do want to keep away from using too much reflection (.getClass()
in particular) as it is a slower opreation.
Oh, and if you're impressed by the website, you might be interested in whats backing it. I've used Jekyll, Asciidoc, and Travis to generate the site directly from Github. Makes editing the site easy because its just a PR or push to master. In fact, you can edit the contents via github's web interface.
Here's the github repo:https://github.com/johncarl81/parceler-site
And the base "JAQ" project that I help maintain: https://github.com/asciidoctor/jekyll-asciidoc-quickstart
Yep, I also mentioned the annotation, but not this way. It would be great! I think I'd you earn the user about reflection, it is ok. There is no way to work around polymorphism I guess.
Your documentation setup is indeed impressive! Thanks for the info.
I have the following structure:
I put objects of different
Animal
subclasses at runtime. When i deserialize the parcel, i only get backAnimal
objects, and notParrot
,Tiger
etc. I tried toimplementations
field of theParcel
annotations onAnimal
, but it fails with the following exception:If i remove the
@Parcel
annotation fromTiger
, i got this