オブジェクトのリストを含むパーセル可能なオブジェクトを渡す方法は?


96

Parcelable以下のオブジェクトを作成しましたList。このオブジェクトには製品が含まれています。私のコンストラクタでは、どうやって自分の再作成を処理ParcelableするのListですか?

私は小包から利用可能なすべての方法をチェックしました、そして利用可能なすべてはですreadArrayList(ClassLoader)。これが最善のアプローチかどうかはわかりませんが、あなたのアドバイスをいただければ幸いです。

public class Outfits implements Parcelable {

    private String url;
    private String name;
    private List<Product> products;

    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Product> getProducts() {
        return products;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public void writeToParcel(Parcel dest, int flags) {
        Log.v("", "writeToParcel..." + flags);
        dest.writeString(url);
        dest.writeString(name);
        dest.writeList(products);
    }


    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Outfits createFromParcel(Parcel in) {
            return new Outfits(in);
        }

        public Outfits[] newArray(int size) {
            return new Outfits[size];
        }
    };

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

    /*** Here how do I populate my List of Products ***/
    private Outfits(Parcel in) {
        url = in.readString();
        name = in.readString();
        products = in.read ???????;
    }
}

そして、何が問題になっていreadList()ますか?
Alex Gitelman、2011年

タイプParcelのメソッドreadList(List、ClassLoader)は、引数()には適用できません
Byron

引数に問題はありません。これが、リストがよく使用される方法です。答えを追加しました。
Alex Gitelman、2011年

回答:


102

クラスProductがparcelableプロトコルと互換性がある場合、以下はドキュメントに従って機能するはずです。

products = new ArrayList<Product>();
in.readList(products, Product.class.getClassLoader());

必ずしも。ドキュメントには、メソッドでwriteList()記述された仕様に従ってオブジェクトを書き込むと記載されていwriteValue()ます。developer.android.com/reference/android/os/…とりわけ、オブジェクトは直列化可能であると述べています。readList()の対応でwriteList()あり、同じデータを読み取ります。
Alex Gitelman、2011年

6
@AlexGitelmanしかし、シリアライゼーションを使用するとパフォーマンスが低下すると見なされているため、Parcableを利用できるようにしたので、これは意味がありません。
eric.itzhak

30
私はこのソリューションをそのまま使用することができませんでした。ClassLoaderがnullでin.readList(products,null);、次のような例外が発生しています...原因:android.os.BadParcelableException:ClassNotFoundException when unmarshalling:com.example.MyApplication.Product。私にとって実際に機能するリストを読むためのバリエーションはin.readList(products,Product.class.getClassLoader());
Peter Dietz

2
製品がSerializableを実装する必要があることも忘れないでください
agmezr

40

まず、Productオブジェクトは Parcelable

そしてdest.writeTypedList(products)writeToParcel()メソッドで使用します。

最後に、次のコードを使用してリストを解析します。

products = new ArrayList<Product>();
in.readTypedList(products, Product.CREATOR);

詳細については、公式ドキュメントを参照してください。


6

私の個人的な経験では、http://www.parcelabler.com/はこのための素晴らしいサイトです。クラスを作成し、それをWebサイトにコピーして貼り付けるだけで、クラスのParcelableバージョンが生成されます。

次の変数を含む "Theme"という名前のクラスでテストしました。

private String name;
private int image;
private List<Card> cards;

writeToParcel関数は次のようになります。

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(image);
    if (cards == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeList(cards);
    }
}

生成されたコンストラクタ:

protected Theme(Parcel in) {
    name = in.readString();
    image = in.readInt();
    if (in.readByte() == 0x01) {
        cards = new ArrayList<Card>();
        in.readList(cards, Card.class.getClassLoader());
    } else {
        cards = null;
    }
}

編集:カードオブジェクトがParcelableであることを確認してください!


5

これはうまくいくはずです:

in.readTypedList(products, Product.CREATOR);

1
それは私にとって問題を引き起こしています、これはよりうまくいきます: products = new ArrayList<Product>(); in.readList(products, Product.class.getClassLoader());
Shyam Sunder

1

ParcelableProductクラスにも実装してから

in.readList(this.list, Product.class.getClassLoader());

上記の解決策のいずれかが機能しなかった場合。


1

もう1つの方法は、readValueおよびwriteValueを使用すること です

protected Product (Parcel in) {
        ...
        in.readValue(this.getClass().getClassLoader());
    }

@Override
public void writeToParcel(Parcel parcel, int i) {
    ...
    parcel.writeValue(**list**);
}

リストの項目はParcelableを実装する必要があります


1

どうぞ...

「Products.java」がParcelableで拡張されていることを確認してください

ステップ1:

 private List<Products> products; 

ステップ2:

private Outfits(Parcel in) {
    products = in.createTypedArrayList(Products.CREATOR);
}

ステップ3:

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeTypedList(products);
    }

0

Productがを実装していると仮定すると、Parcelableこれを使用して記述できます。

dest.writeValue(products);

そしてこれは読むために:

products = (List<Product>) in.readValue(Product.class.getClassLoader());

0

製品はParcelableを実装する必要があります

  Product class implements  Parcelable {
          ......
  }

次に、オブジェクトが次のようなリストを含むと書き込みます

public class Outfits implements Parcelable {

     private String url;
     private String name;
     private List<Product> products;

     public Outfits (Parcel pi) {

        bookName = p.readString();
        bookId = p.readInt();
        isColor = p.readInt() == 1;

        //use this well be get err
        //products=p.readArrayList(Thread.currentThread().getContextClassLoader());

        //Pass list use this 
        products= in.createTypedArrayList(Product.CREATOR);

      }

            ...get and set...

     public void writeToParcel(Parcel dest, int flags) {


        dest.writeString(url);
        dest.writeString(name);

        //use this will no working
        //dest.writeList(products);

        //Parcelable list
        out.writeTypedList(products);

     }

 }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.