Parceler打开错误的数据

时间:2015-08-08 12:48:51

标签: android parcelable parcel parceler

我正在使用parceler库来实现Parcelable接口。

我有这样的模特

@Parcel(Parcel.Serialization.BEAN)
public class Ads {
private Long id;
private String title;
private String description;
private AdsType adsType;
private String phone;
private String email;
private String city;
private Long categoryId;
private ArrayList<Integer> creationDate;
//TODO remove transient
private transient ArrayList<Long> imageIds;
private transient Long price;


@SerializedName("adsCategory")
private AdvCategory advCategory;

public Ads() {}

public Ads(String title, String description, AdsType adsType, String
        phone, String email, String city, Long categoryId, Long price, ArrayList<Long> imageIds) {
    this.title = title;
    this.description = description;
    this.adsType = adsType;
    this.phone = phone;
    this.email = email;
    this.city = city;
    this.categoryId = categoryId;
    this.price = price;
    this.imageIds = imageIds;
}

@ParcelConstructor
public Ads(Long id, String title, String description, AdsType adsType,
           String phone, String email, String city, ArrayList<Long>
                   imageIds, Long price, ArrayList<Integer> creationDate, AdvCategory advCategory) {
    this.id = id;
    this.title = title;
    this.description = description;
    this.adsType = adsType;
    this.phone = phone;
    this.email = email;
    this.city = city;
    this.imageIds = imageIds;
    this.price = price;
    this.creationDate = creationDate;
    this.advCategory = advCategory;
}

public Long getId() {
    return id;
}

public String getTitle() {
    return title;
}

public String getDescription() {
    return description;
}

public AdsType getAdsType() {
    return adsType;
}

public String getPhone() {
    return phone;
}

public String getEmail() {
    return email;
}

public String getCity() {
    return city;
}

public AdvCategory getAdvCategory() {
    return advCategory;
}

public void setAdvCategory(AdvCategory advCategory) {
    this.advCategory = advCategory;
}

public Long getCategoryId() {
    return categoryId;
}

public ArrayList<Long> getImageIds() {
    return imageIds;
}

public void setImageIds(ArrayList<Long> imageIds) {
    this.imageIds = imageIds;
}

public int getPrice() {
    //TODO replace with real price
    return new Random().nextInt(100000);
}

public void setPrice(Long price) {
    this.price = price;
}

public ArrayList<Integer> getCreationDate() {
    return creationDate;
}

public void setCreationDate(ArrayList<Integer> creationDate) {
    this.creationDate = creationDate;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Ads ads = (Ads) o;
    return id.equals(ads.id);
}

@Override
public int hashCode() {
    int result = id.hashCode();
    result = 31 * result + title.hashCode();
    result = 31 * result + description.hashCode();
    result = 31 * result + adsType.hashCode();
    result = 31 * result + (phone != null ? phone.hashCode() : 0);
    result = 31 * result + (email != null ? email.hashCode() : 0);
    result = 31 * result + (city != null ? city.hashCode() : 0);
    result = 31 * result + advCategory.hashCode();
    result = 31 * result + (categoryId != null ? categoryId.hashCode() : 0);
    return result;
}

@Override
public String toString() {
    return "Ads{" +
            "id=" + id +
            ", title='" + title + '\'' +
            ", description='" + description + '\'' +
            ", adsType=" + adsType +
            ", phone='" + phone + '\'' +
            ", email='" + email + '\'' +
            ", city='" + city + '\'' +
            ", creationDate='" + creationDate.toString() +
            '}';
}

public static class List extends ArrayList<Ads> {}
}

我正在包装我的模型并将其置于意图之中。

 Intent adsDetailsIntent = new Intent(this, AdsDetailsActivity.class);
    Bundle details = new Bundle();
    Ads advertisement = mAdsAdapter.getItem(position);
    details.putParcelable(AdsDetailsActivity.ADS_DETAILS, Parcels.wrap(advertisement));
    Ads ads = Parcels.unwrap(details.getParcelable(AdsDetailsActivity.ADS_DETAILS));
    Log.d("ads", ads.toString());
    adsDetailsIntent.putExtras(details);
    startActivity(adsDetailsIntent);

在活动中展开

mAdsDetails = Parcels.unwrap(
            (Parcelable) this.getIntent().getParcelableExtra(ADS_DETAILS));

但有时字段“creationDate”在展开活动后有错误的值。

我尝试记录它,从Bundle中解压后 - 没关系,但在活动中 - 它有奇怪的数据。

示例:

  

创建后立即从包中解包

     

广告{id = 16,title ='Mtitle',description ='Mads',adsType = BUY,phone ='+ 30890931231',email ='+ 380932309046',city ='Анабарскийнациональныйулус',creationDate =' [2015,8,8,9,27,0,350946000]}

     

从活动intent.getExtra()

解包      

广告{id = null,title ='null',description ='null',adsType = null,phone ='null',email ='null',city ='null',creationDate ='[8,8 ,9,27,0,350946000,null,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

我不知道为什么,但它正在创建一个大小为creationDate 1的数组,并用零填充它。

2 个答案:

答案 0 :(得分:0)

我注意到你打开课堂

mAdsDetails = Parcels.unwrap(
            (Parcelable) this.getIntent().getParcelableExtra(ADS_DETAILS));

你有没有尝试过这种方式:

mAdsDetails = Parcels.unwrap(this.getIntent().getExtras().get(ADS_DETAILS));

答案 1 :(得分:0)

我认为这可能与int函数的#getPrice返回类型和注释时带有的构造函数的Long参数的price类型之间的差异有关。 @ParcelConstructor

这将导致生成的代码:

  1. 将整数写入包中进行序列化
  2. 尝试在反序列化时读取复杂的更大类型
  3. 反序列化继续,但有效地读取垃圾,因为readFoo方法被调用&#34;错误&#34;缓冲区中的偏移量
  4. 具体来说,在检查Parceler生成的代码并在我的代码中调试相同的问题时,我发现:

    • 原始类型作为单个值直接写入parcel
    • 复杂类型(如原始类型的包装器)使用两个值写入:一个用于null而非 - null用作标志,然后可能是实际值,如果不是null

    请参阅我为Parceler项目制作的这个问题:

    https://github.com/johncarl81/parceler/issues/234