Problem in implementing Parcelable containing other Parcelable

前端 未结 2 568
不思量自难忘°
不思量自难忘° 2020-12-31 22:21

I\'m implementing Parcelable class that has another Parcelable insde.

In OuterParcelable class:

@Override
public void writeToParcel(Parcel dest, int          


        
相关标签:
2条回答
  • 2020-12-31 22:30

    A clean way to store non-primitive attributes as parcelable, possibly null, values. Use Parcel.writeValue() and readValue(). See comments in code below:

    public class MyParcelableClass implements Parcelable {
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeValue(getIntegerAttribute()); // getIntegerAttribute() returns Integer
            dest.writeValue(getDoubleAttribute());
            dest.writeValue(getMyEnumAttribute()); // getMyEnumAttribute() returns a user defined enum
            dest.wrtieValue(getUserClassAttribute()); //UserClass must implement Parcelable in a similar fashion
        }
    
        private MyParcelableClass(Parcel in) {
            setIntegerAttribute((Integer)in.readValue(null)); //pass null to use default class loader. Ok for Integer, String, etc.
            setDoubleAttribute((Double)in.readValue(null)); //Cast to your specific attribute type
            setEnumAttribute((MyEnum)in.readValue(null));
            setUserClassAttribute((UserClass)in.readValue(UserClass.class.getClassLoader())); //Use specific class loader
        }
    
        @Override
        public int describeContents() ...
    
        public static final Parcelable.Creator<ParcelableLocationBean> CREATOR ...    
    }
    

    Works like a charm. writeValue() and readValue() encapsulate the dealing with possible nulls and type detection. From javadoc:

    public final void writeValue (Object v)
    Flatten a generic object in to a parcel. The given Object value may currently be one of the following types:
    null, String, Integer, ...
    String[], boolean[], ...
    Any object that implements the Parcelable protocol. ...

    0 讨论(0)
  • 2020-12-31 22:45

    Why are you putting the value into a Bundle? Did you completely implement the parcelable in your class?

    Parcelable Skeleton

    public MyClass(Parcel in) {
        readFromParcel(in);
    }
    
        //
    // Parcelable Implementation
    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) { 
        dest.writeParcelable(aParcelableClass, flags);
    }
    
    private void writeObject(Parcel dest, Object obj) {
        if (obj != null) {
            dest.writeInt(1);
            dest.writeValue(obj);
        } else {
            dest.writeInt(0);
        }
    }
    
    public void readFromParcel(Parcel in) {
        aParcelableClass = in.readParcelable(ParcelableClass.class.getClassLoader());
    }
    
    private Object readObject(Parcel in) {
        Object value = null;
    
        if (in.readInt() == 1) {
            value = in.readValue(null); // default classloader
        }
    
        return value;
    }
    
    public static final Parcelable.Creator<MyClass> CREATOR = new Parcelable.Creator<MyClass>() {
        @Override
        public MyClass createFromParcel(Parcel source) {
            return new MyClass(source);
        }
    
        @Override
        public MyClass[] newArray(int size) {
            return new MyClass[size];
        }
    };
    

    I added a few things to make null values more easily dealt with, but the principle is the same. You need the @Override items, constructor, and Creator.

    If you're going to read and write a parcelable you will have issues if you specify null as the class loader.

    0 讨论(0)
提交回复
热议问题