1

I am building an Android app which connects to a REST server and I get this error in class that models server's response:

Error:(16, 15) error: Parceler: Unable to find read/write generator for type java.lang.Object for com.myapp.ServerResponse.result

I think the error is because I use generic type E. ServerResponse.java is:

public class ServerResponse <E> {
    @SerializedName("status")
    private int status;

    @SerializedName("result")
    private E result;

    @SerializedName("message")
    private String message;

    //Getters and setters
}

Is any way to solve this issue?

John Ericksen
  • 10,995
  • 4
  • 45
  • 75
Angel F.
  • 176
  • 1
  • 16

2 Answers2

2

Parceler opts for speed in this case so it will not use the Parcels.wrap/unwrap() by default, but if you'd like to handle generics you can use a @ParcelPropertyConveter that uses the Parcels.wrap()/unwrap() methods:

@Parcel
public class ServerResponse <E> {

    @ParcelPropertyConverter(ParcelsWrapperConverter.class)
    private E result;
}

public class ParcelsWrapperConverter extends NullableParcelConverter<Object> {

    @Override
    public void nullSafeToParcel(Object input, android.os.Parcel parcel) {
        parcel.writeParcelable(Parcels.wrap(input), 0);
    }

    @Override
    public Object nullSafeFromParcel(android.os.Parcel parcel) {
        return Parcels.unwrap(parcel.readParcelable(ParcelsWrapperConverter.class.getClassLoader()));
    }
}

Just be sure the values you use in the ServerResponse are annotated with @Parcel or else Parcels will throw a runtime exception.

John Ericksen
  • 10,995
  • 4
  • 45
  • 75
0

You're right that you can't Parcel generics. (You can't Serialize unbounded generics either!)

When you have an instance of a generic class, that instance has its type erased at runtime so that there are only concrete types. At runtime, all instances of a generic type parameter are replaced by its bounds. Unbounded parameters like you use here are replaced by Object.

You might be able to do:

@Parcel
public class ServerResponse<E extends Parcelable> {
    @SerializedName("result")
    private E result;
}

This would replace E with Parcelable when the type is erased. The Parceler library claims to support any Parcelable types. You will need to make sure that the value in Result is parcelable, but you already need that to send it in a Parcel.

joeblubaugh
  • 1,127
  • 7
  • 10
  • This error disappeared. Now I have this: Error:Execution failed for task ':app:compileDebugJava'. > org.parceler.transfuse.TransfuseAnalysisException: @Parcel code generation did not complete successfully. – Angel F. Jul 15 '15 at 19:12