使用 Parcelable 在活动之间传递高度嵌套 类

Using Parcelable to pass highly nested classes between Activities

假设我想在 Intent 中存储类型 MyObject 的自定义对象。这样做的方法是让 MyObject 实现 Parcelable。如果 MyObject 的字段之一也是类型 Widget 的自定义对象,显而易见的事情是让 Widget 也实现 Parcelable

问题在于实施时涉及大量样板 Parcelable。你可以通过不让 Widget 实现 Parcelable 来解决这个问题,而是只给它一个采用 Parcel 和方法 writeToParcel 的构造函数,如下所示:

public final class Widget {

    private final int a;
    private final String b;

    Widget(Parcel in) {
        a = in.readInt();
        b = in.readString();
    }

    void writeToParcel(Parcel out) {
        out.writeInt(a);
        out.writeString(b);
    }
}

然后您可以在 Parcelable 对象中有一个 Widget 字段,如下所示:

public class MyObject implements Parcelable {

    private final int x;
    private final Widget w;

    MyObject(int x, Widget w) {
        this.x = x;
        this.w = w;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(x);
        w.writeToParcel(out);
    }

    public static final Parcelable.Creator<MyObject> CREATOR
            = new Parcelable.Creator<MyObject>() {
        @Override
        public MyObject createFromParcel(Parcel in) {
            return new MyObject(in.readInt(), new Widget(in));
        }
        @Override
        public MyObject[] newArray(int size) {
            return new MyObject[size];
        }
    };
}

这是可以接受的方法吗?在一个项目中有许多自定义 类 可以写入和读取 Parcel 而无需它们实际实现 Parcelable 是否被认为是单一的 android?或者我正在使用 Parcelable 传递具有许多自定义类型字段的复杂对象(这些字段又具有许多自定义类型字段等)这一事实表明我不应该使用 Parcelable 首先?

在处理通过 Android 中的意图传递自定义对象时,建议使用 Parcelable。没有 "easy" 解决方法。由于您只处理一个额外级别的自定义对象(小部件),我建议您也制作 Widget Parcelable。您还可以查看此 link 以了解为什么它比使用默认序列化更好。 https://coderwall.com/p/vfbing/passing-objects-between-activities-in-android

我愿意(并且确实)选择 Parceler:https://github.com/johncarl81/parceler

Parceler is a code generation library that generates the Android Parcelable boilerplate source code. No longer do you have to implement the Parcelable interface, the writeToParcel() or createFromParcel() or the public static final CREATOR. You simply annotate a POJO with @Parcel and Parceler does the rest.

真的好用

如果您的 classes 是 beans,最好的解决方案是公认的解决方案。如果没有,我发现您可以(稍微)通过创建抽象 classes ParcelablePlusCreatorPlus 来减轻实现 Parcelable 的痛苦。

ParcelablePlus:

abstract class ParcelablePlus implements Parcelable {

    @Override
    public final int describeContents() {
        return 0;
    }
}

CreatorPlus:

abstract class CreatorPlus<T extends Parcelable> implements Parcelable.Creator<T> {

    private final Class<T> clazz;

    CreatorPlus(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    @SuppressWarnings("unchecked")
    public final T[] newArray(int size) {
        // Safe as long as T is not a generic type.
        return (T[]) Array.newInstance(clazz, size);
    }
}

然后 Widget class 变成:

public final class Widget extends ParcelablePlus {

    private final int a;
    private final String b;

    Widget(int a, String b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(a);
        out.writeString(b);
    }

    public static final Creator<Widget> CREATOR = new CreatorPlus<Widget>(Widget.class) {
        @Override
        public Widget createFromParcel(Parcel in) {
            return new Widget(in.readInt(), in.readString());
        }
    };
}