Write a sub class of Parcelable to another Parcel

前端 未结 3 2071
盖世英雄少女心
盖世英雄少女心 2020-12-23 09:15

I have a class that implements Parcelable interface:

class A implements Parcelable {

}

I have another class B th

相关标签:
3条回答
  • 2020-12-23 09:25

    A better way to handle this that avoids reflexion would be to simply call the static creator in the target type like this:

    this.amazingObject = AmazingObject.CREATOR.createFromParcel(in);
    

    and write it to the Parcelable using this.amazingObject.writeToParcel(Parcel, int)

    Internally, when calling readParcelable(ClassLoader) this happens:

    public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
        Parcelable.Creator<T> creator = readParcelableCreator(loader);
        if (creator == null) {
            return null;
        }
        if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
            return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
        }
        return creator.createFromParcel(this);
    }
    

    As you can see the last call of that method is just calling the right Creator but inside readParcelableCreator there is a whole lot of reflexion that we can avoid by just calling it directly.

    This utility calls may be useful:

    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Parcels {
    
        public static void writeBoolean(Parcel dest, Boolean value) {
            dest.writeByte((byte) (value != null && value ? 1 : 0));
        }
    
        public static Boolean readBoolean(Parcel in){
            return in.readByte() != 0;
        }
    
        public static void writeParcelable(Parcel dest, int flags, Parcelable parcelable) {
            writeBoolean(dest, parcelable == null);
            if (parcelable != null) {
                parcelable.writeToParcel(dest, flags);
            }
        }
    
        public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<T> creator) {
            boolean isNull = readBoolean(in);
            return isNull ? null : creator.createFromParcel(in);
        }
    
    }
    
    0 讨论(0)
  • 2020-12-23 09:34

    The line:

    obj = (A)in.readParcelable(A.class.getClassLoader());
    

    should change to:

    obj = (A)in.readParcelable(B.class.getClassLoader());
    

    I encountered the same problem and did several Google search, many webpage or tutorial suggests we use A.class.getClassLoader() because we are casting to A, but actually it is WRONG because you will get a null value, we must use B.class.getClassLoader() because the codes are INSIDE class B. I just did not know why but it can get the correct A object in this way.

    Welcome to comment and verify!!

    0 讨论(0)
  • 2020-12-23 09:36
    class B implements Parcelable{
    //lets assume you have A as a data member 
    
    A obj;
    public void writeToParcel(Parcel dest, int flags) {
    
            dest.writeParcelable(obj , flags);
    
        }
    }
    

    if you want to read it use this

     obj = in.readParcelable(A.class.getClassLoader());
    
    0 讨论(0)
提交回复
热议问题