개체 목록이 포함 된 구획 가능 개체를 전달하는 방법은 무엇입니까?


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

답변:


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
이 솔루션을 그대로 사용하는 것은 운이 좋지 않았습니다. null의 ClassLoader in.readList(products,null);, 다음과 같은 예외가 발생합니다. 원인 : android.os.BadParcelableException : Unmarshalling시 ClassNotFoundException : com.example.MyApplication.Product. 실제로 나를 위해 작동 목록을 읽을 수있는 변화입니다in.readList(products,Product.class.getClassLoader());
피터 디 에츠

2
또한 제품이 Serializable을 구현해야 함을 잊지 마십시오
agmezr

40

먼저 Product 객체는 Parcelable.

그리고, 사용 dest.writeTypedList(products)writeToParcel()방법.

마지막으로 다음 코드를 사용하여 목록을 구문 분석합니다.

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

자세한 내용은 공식 문서 를 참조하십시오 .


6

개인적으로 http://www.parcelabler.com/ 은 이것에 대한 놀라운 사이트입니다. 클래스를 만들고 복사하여 웹 사이트에 붙여 넣으면 클래스의 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());
시암 선더

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.