将Parcelable的子类写入另一个Parcel


67

我有一个实现Parcelable接口的类:

class A implements Parcelable {

}

我还有另一个B包含一个A对象作为实例变量的类。在writeToPacel内部类B,我想写对象BParcel

class B implements Parcelable{

    public void writeToParcel(Parcel dest, int flags) {
        dest.write ??? 
    }
}

我该如何读写?


A object里面的B在哪里?
iTurki 2012年

Answers:


168
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);

    }
}

如果您想阅读,请使用此

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

6
无需铸造:)
pablisco 2014年

4
您甚至可以更加精确:obj = (A) in.<A>readParcelable(A.class.getClassLoader());
caw

1
al不需要强制转换!
sud007 '16

11

避免反射的更好方法是像这样在目标类型中简单地调用静态创建者:

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

并写入Parcelable使用this.amazingObject.writeToParcel(Parcel, int)

在内部,readParcelable(ClassLoader)发生这种情况时:

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);
}

如您所见,该方法的最后一次调用只是调用正确的方法,Creator但是在内部readParcelableCreator却有很多反射,我们可以通过直接调用它来避免。

该实用程序调用可能有用:

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);
    }

}

1
当对象为null时,它将引发异常,同时可以readParcelable正确处理这种情况
dragoon 2014年

@dragoon您有什么例外?
pablisco 2014年

我最终使用了自己的Parcel Util,但感谢您的启发!
Juan Saravia

2

该行:

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

应更改为:

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

我遇到了同样的问题,并做了几次Google搜索,很多网页或教程建议我们使用它,A.class.getClassLoader()因为我们正在转换为A,但实际上它是WRONG,因为您将获得一个空值,我们必须使用,B.class.getClassLoader()因为codes are INSIDE class B。我只是不知道为什么,但是它可以通过这种方式获得正确的A对象。

欢迎发表评论并验证!!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.