Search code examples
androidparceler

Parceler - unable to find read/write generator for SpannableString


Error:(27, 64) error: Parceler: Unable to find read/write generator for type android.text.SpannableString for android.text.SpannableString span2
Error:(27, 87) error: Parceler: Unable to find read/write generator for type android.text.SpannableString for android.text.SpannableString span3
Error:(27, 41) error: Parceler: Unable to find read/write generator for type android.text.SpannableString for android.text.SpannableString span1

I'm getting the above error when I try to build my project. As the classes I'm using are SpannableString I know I require some custom serialization which I believe I have implemented. Any ideas?

See my code below:

@Parcel
public class ParcelerTest
{
    @ParcelPropertyConverter(SpannableStringParcelConverter.class)
    public SpannableString span1;

    @ParcelPropertyConverter(SpannableStringParcelConverter.class)
    public SpannableString span2;

    @ParcelPropertyConverter(SpannableStringParcelConverter.class)
    public SpannableString span3;

    @ParcelConstructor
    public ParcelerTest(SpannableString span1, SpannableString span2, SpannableString span3)
    {
        this.span1 = span1;
        this.span2 = span2;
        this.span3 = span3;
    }

    public class SpannableStringParcelConverter implements ParcelConverter
    {
        @Override
        public void toParcel(Object input, android.os.Parcel parcel)
        {
            parcel.writeParcelable(Parcels.wrap(parcel), 0);
        }

        @Override
        public Object fromParcel(android.os.Parcel parcel)
        {
            return Parcels.unwrap(parcel.readBundle(getClass().getClassLoader()));
        }
    }
}

Solution

  • Ah, there's a couple problems here, some are legitimate bugs:

    1. You need to define your inner class as static. Parceler should have a better error about this.
    2. You need to annotate the constructor parameters. This is a legitimate bug, you should be able to annotate either.
    3. Your ParcelConverter should write and read the contents of SpannableString, Parceler doesn't handle this type directly. This would cause a runtime error if you tested it.

    Here's an updated working version of your code:

    @Parcel
    public class ParcelerTest
    {
        public SpannableString span1;
        public SpannableString span2;
        public SpannableString span3;
    
        @ParcelConstructor
        public ParcelerTest(@ParcelPropertyConverter(SpannableStringParcelConverter.class) SpannableString span1,
                            @ParcelPropertyConverter(SpannableStringParcelConverter.class) SpannableString span2,
                            @ParcelPropertyConverter(SpannableStringParcelConverter.class) SpannableString span3)
        {
            this.span1 = span1;
            this.span2 = span2;
            this.span3 = span3;
        }
    
        public static class SpannableStringParcelConverter implements ParcelConverter<SpannableString>
        {
            @Override
            public void toParcel(SpannableString input, android.os.Parcel parcel)
            {
                parcel.writeString(input.toString());
            }
    
            @Override
            public SpannableString fromParcel(android.os.Parcel parcel)
            {
                return new SpannableString(parcel.readString());
            }
        }
    }
    

    Also, it's a little strange to use a SpannableString in the model of your codebase. Maybe you could just use a plain String instead?