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