Can autostart-adapter-package handle Typed Set of another class with automatic value?

I am studying auto-value and its extensions, namely auto-value-parcel and auto-value-parcel-adapter in my Android app.

I have these model classes: -

 @AutoValue public abstract class Xenarchaeota implements Parcelable { @ParcelAdapter(AmoebaTypeAdapter.class) public abstract Set<Amoeba> amoebas(); public static Builder builder() { return new AutoValue_Xenarchaeota.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setAmoebas(Set<Amoeba> value); public abstract Xenarchaeota build(); } } 

and

 @AutoValue public abstract class Amoeba implements Parcelable { public abstract String surname(); public static Builder builder() { return new AutoValue_Amoeba.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder surname(final String value); public abstract Amoeba build(); } } 

There are problems in my type adapter.

 class AmoebaTypeAdapter implements TypeAdapter<Set<Amoeba>> { @Override public Set<Amoeba> fromParcel(Parcel in) { final ArrayList<Amoeba> arrayList = new ArrayList<>(); in.readTypedList(arrayList, Amoeba.CREATOR); // How to access the CREATOR? return new TreeSet<>(arrayList); } @Override public void toParcel(Set<Amoeba> value, Parcel dest) { final ArrayList<Amoeba> arrayList = new ArrayList<>(value); dest.writeTypedList(arrayList); } } 

CREATOR I need to go to readTypedArray declared in AutoValue_Amoeba.

Where is my mistake? misunderstanding auto-value-parcel ?

+7
android parcelable auto-value
source share
2 answers

AutoValue: a package extension cannot handle sets, but if you convert a property to List , everything will work outside the box without a special adapter. If you want to treat it as a Set , you can do it. Keep in mind that you probably also want to cache Set .

 @AutoValue public abstract class Xenarchaeota implements Parcelable { abstract List<Amoeba> amoebaList(); public Set<Amoeba> amoebas() { return new TreeSet(amoebaList()); } public static Builder builder() { return new AutoValue_Xenarchaeota.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setAmoebas(Set<Amoeba> value); public abstract Xenarchaeota build(); } } 
+3
source share

I believe that I defined the solution as follows: -

Currently class auto-value-parcel

 com.ryanharter.auto.value.parcel.AutoValueParcelExtension 

has a method called generateCreator : -

 FieldSpec generateCreator(ProcessingEnvironment env, TypeName autoValueType, List<Property> properties, TypeName type, Map<TypeMirror, FieldSpec> typeAdapters) { ClassName creator = ClassName.bestGuess("android.os.Parcelable.Creator"); TypeName creatorOfClass = ParameterizedTypeName.get(creator, type); ... ... 

This method generates a Parcelable CREATOR that resembles this

 public static final Parcelable.Creator<AutoValue_Amoeba> CREATOR = new Parcelable.Creator<AutoValue_Amoeba>() { @Override public AutoValue_Amoeba createFromParcel(Parcel in) { return new AutoValue_Amoeba( in.readString() ); } @Override public AutoValue_Amoeba[] newArray(int size) { return new AutoValue_Amoeba[size]; } }; 

If the generateCreator method has been changed as follows: -

 FieldSpec generateCreator(ProcessingEnvironment env, TypeName autoValueType, List<Property> properties, TypeName type, Map<TypeMirror, FieldSpec> typeAdapters) { ClassName creator = ClassName.bestGuess("android.os.Parcelable.Creator"); TypeName creatorOfClass = ParameterizedTypeName.get(creator, autoValueType); // CHANGE MADE HERE!!! swap type with autoValueType ... ... 

This method will then generate a Parcelable CREATOR that will look like this

 public static final Parcelable.Creator<Amoeba> CREATOR = new Parcelable.Creator<Amoeba>() { @Override public AutoValue_Amoeba createFromParcel(Parcel in) { return new AutoValue_Amoeba( in.readString() ); } @Override public AutoValue_Amoeba[] newArray(int size) { return new AutoValue_Amoeba[size]; } }; 

This CREATOR now allows the TypeAdapter to use the CREATOR, as shown here.

 class AmoebaTypeAdapter implements TypeAdapter<Set<Amoeba>> { @Override public Set<Amoeba> fromParcel(Parcel in) { final List<Amoeba> arrayList = new ArrayList<>(); in.readTypedList(arrayList, AutoValue_Amoeba.CREATOR); return new TreeSet<>(arrayList); } @Override public void toParcel(Set<Amoeba> value, Parcel dest) { final ArrayList<Amoeba> arrayList = new ArrayList<>(value); dest.writeTypedList(arrayList); } } 
+2
source share

All Articles