Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to parcel java.lang.Class objects in a generic way? #374

Open
StephanSchuster opened this issue Sep 6, 2019 · 0 comments
Open

How to parcel java.lang.Class objects in a generic way? #374

StephanSchuster opened this issue Sep 6, 2019 · 0 comments

Comments

@StephanSchuster
Copy link

I have the following generic Data container:

@Parcel
public class Data implements Cloneable {

    @ParcelPropertyConverter(ValuesParcelConverter.class)
    SparseArray<Object> mValues;

    ...
}

The ValuesParcelConverter does this:

        public void toParcel(SparseArray<Object> values, android.os.Parcel parcel) {
            if (values == null) {
                parcel.writeInt(-1);
            } else {
                int size = values.size();
                parcel.writeInt(size);
                for (int i = 0; i < size; ++i) {
                    int id = values.keyAt(i);
                    Object value = values.valueAt(i);
                    parcel.writeInt(id);
                    try {
                        parcel.writeParcelable(Parcels.wrap(value), 0);
                    } catch (Exception e) {
                        ...
                    }
                }
            }
        }

Problem: If a value is a class object (e.g. MyClass.class) it of course cannot be serialized.
Question: What's the best approach to enable this for my generic Data container?

Option 1: Bad but works:
Check each value before wrapping if its an instance of Class and if so, serialize the class name to string via Class.getName() and prefix it with some magic string. On deserializing check each value if it's an instance of String and starts with the magic prefix. If yes strip the prefix and use Class.forName(). While the serializing mechanism (Class -> String -> Class) is okay, I don't wanna check this for each value because of performance. In worst case none of 1000 values is a class object. And I do NOT know the values beforehand.

Option 2: Hopefully better but not working:

@ParcelClass(
        value = Class.class,
        annotation = @Parcel(converter = MyClassConverter.class))
public class App extends BaseApp {

MyClassConverter is doing the serialization via Class.getName() and Class.forName(). But this results in the following error:

Unable to find generated Parcelable class for java.lang.Class, verify that your class is configured properly and that the Parcelable class java.lang.Class$$Parcelable is generated by Parceler.

Looking at the generated source I see the following Class: java_.lang.Class$$Parcelable
Is this underscore on purpose? Is this why it's failing? Is this approach even valid? Did I misunderstand something here?

Any help would be appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant