2015-08-08 152 views
3

假设我想将MyObject类型的自定义对象存储在Intent中。做到这一点的方法是使MyObject实施Parcelable。如果MyObject的其中一个字段也是Widget类型的自定义对象,则明显的做法是使Widget也实现Parcelable使用Parcelable在活动之间传递高度嵌套的类

问题在于执行Parcelable时涉及大量的样板文件。

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对象,如下所示:您可以通过不使Widget实施Parcelable而只是给它一个构造采取Parcel和方法writeToParcel如下解决这个

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

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

回答

2

我会(也没有)与Parceler去:https://github.com/johncarl81/parceler

Parceler是产生了Android Parcelable样板源代码,一个代码生成库。您不再需要实现 的Parcelable接口,writeToParcel()或createFromParcel()或Public static final CREATOR。你只需用 @Parcel注释POJO,Parceler就可以完成剩下的工作。

这真的很容易使用。

0

建议在处理通过Android中的意图传递自定义对象时使用Parcelable。没有一个“简单”的工作。既然你只处理一个额外的自定义对象(Widget),我建议你也制作WidgetParcelable。你也可以查看这个链接,看看为什么它比使用默认序列化更好。 https://coderwall.com/p/vfbing/passing-objects-between-activities-in-android

+0

不幸的是,这仅仅是一个例子。我认为我的物体实际上是4-5层。 –

+0

非正统的做法是如果你有一个静态字段的类,你可以在活动之间进行更新。 例如**活动A **将在开始**活动B **的意图之前更新静态类中的MyObject'字段,然后在**活动B **中它将从该活动B **中读取“MyObject”字段静态类。这样,你根本不需要考虑可接受的包裹 –

+0

@PaulBoddington look above –

0

如果你的课程是豆类,最好的解决方案是接受的。如果没有,我发现你可以(稍微)减少执行Parcelable的痛苦,通过创建抽象类ParcelablePlusCreatorPlus像这样。

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