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

时间:2015-08-08 18:31:27

标签: android parcelable

假设我想在MyObject中存储Intent类型的自定义对象。这样做的方法是使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);
    }
}

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

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,它是否被视为unidiomatic android?或者我使用Parcelable传递具有许多自定义类型字段的复杂对象(这又包含许多自定义类型等字段等),这表明我不应该使用{{ 1}}首先?

3 个答案:

答案 0 :(得分:2)

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

  

Parceler是一个生成Android的代码生成库   可分类的样板源代码。你不再需要实施   Parcelable接口,writeToParcel()或createFromParcel()或   公共静态最终CREATOR。您只需使用注释POJO即可   @Parcel和Parceler完成剩下的工作。

这很容易使用。

答案 1 :(得分:0)

建议在处理通过Android中的意图传递自定义对象时使用Parcelable。没有&#34;容易&#34;解决。由于您只处理一个额外级别的自定义对象(Widget),我建议您同时使用Widget Parcelable。您还可以查看此链接,了解为什么它比使用默认序列化更好。 this link.

答案 2 :(得分:0)

如果你的课程是豆类,那么最好的解决方案就是被接受的。如果没有,我发现您可以(略微)通过创建这样的抽象类ParcelableParcelablePlus来减轻实施CreatorPlus的痛苦。

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类成为:

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