วิธีการส่งวัตถุที่สามารถจัดส่งพัสดุที่มีรายการวัตถุ


97

ฉันได้สร้าง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

เมธอด readList (List, ClassLoader) ในประเภท Parcel ไม่สามารถใช้ได้กับอาร์กิวเมนต์ ()
Byron

ไม่มีอะไรผิดปกติกับข้อโต้แย้ง นั่นเป็นวิธีที่มักใช้รายการ ฉันเพิ่มคำตอบ
Alex Gitelman

คำตอบ:


104

หากคลาสProductเข้ากันได้กับโปรโตคอลที่สามารถจัดเก็บได้สิ่งต่อไปนี้ควรทำงานตามเอกสารประกอบ

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

ไม่จำเป็น. เอกสารระบุว่าwriteList()จะเขียนวัตถุตามข้อกำหนดที่อธิบายโดยwriteValue()วิธีการ developer.android.com/reference/android/os/…เหนือสิ่งอื่นใดมันบอกว่าวัตถุนั้นสามารถต่ออนุกรมได้ readList()เป็นคู่กันwriteList()และจะอ่านข้อมูลเดียวกัน
Alex Gitelman

6
@AlexGitelman แต่การใช้ serialization ถือว่าไม่ดีสำหรับ preformance นั่นคือเหตุผลที่พวกเขาทำให้ Parcable พร้อมใช้งานจะไม่ทำแบบนี้ที่ทำให้ไม่มีจุดหมาย?
eric.itzhak

30
ฉันไม่มีโชคในการใช้โซลูชันนี้เหมือนที่เป็นอยู่ ClassLoader ของ null in.readList(products,null);ได้รับข้อยกเว้นเช่น ... เกิดจาก: android.os.BadParcelableException: ClassNotFoundException เมื่อ unmarshalling: com.example.MyApplication.Product รูปแบบในการอ่านรายการที่ใช้งานได้จริงสำหรับฉันคือin.readList(products,Product.class.getClassLoader());
Peter Dietz

2
อย่าลืมว่าผลิตภัณฑ์ต้องใช้ Serializable
agmezr

40

Parcelableประการแรกการดำเนินการต้องวัตถุผลิตภัณฑ์ของคุณ

จากนั้นใช้dest.writeTypedList(products)ในwriteToParcel()วิธีการ

สุดท้ายใช้รหัสต่อไปนี้เพื่อแยกวิเคราะห์รายการ:

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

สำหรับข้อมูลเพิ่มเติมโปรดอ้างอิงเอกสารอย่างเป็นทางการ :


6

จากประสบการณ์ส่วนตัวของฉันhttp://www.parcelabler.com/เป็นเว็บไซต์ที่ยอดเยี่ยมสำหรับสิ่งนี้ คุณเพียงแค่สร้างชั้นเรียนของคุณและคัดลอกวางลงในเว็บไซต์จากนั้นจะสร้างชั้นเรียนของคุณในเวอร์ชัน Parcelable

ฉันทดสอบกับคลาสชื่อ "ธีม" ซึ่งมีตัวแปรต่อไปนี้:

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

แก้ไข: ตรวจสอบให้แน่ใจว่าวัตถุการ์ดนั้นเป็นพัสดุภัณฑ์ด้วย!


5

สิ่งนี้ควรใช้งานได้:

in.readTypedList(products, Product.CREATOR);

1
มันกำลังสร้างปัญหาให้กับฉันซึ่งได้ผลดีกว่า: products = new ArrayList<Product>(); in.readList(products, Product.class.getClassLoader());
Shyam Sunder

1

ใช้Parcelableกับคลาสผลิตภัณฑ์ด้วยแล้ว

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

หากวิธีแก้ไขปัญหาใด ๆ ข้างต้นไม่ได้ผล


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.