abalta abalta - 2 months ago 12
Android Question

Parcelable changes resource id on Android

I have Product class which is implements Parcelable. This class have some images these images path keeps in strings.xml. I have product object to another activity, but image resource changes. So, I get ResourcesNotFoundExceptions.

Here my strings.xml

<string-array name="prod_images">
<item>@drawable/sample_product_one</item>
<item>@drawable/sample_product_two</item>
<item>@drawable/sample_product_three</item>
<item>@drawable/sample_product_four</item>
</string-array>


My Product.java class.

public class Product implements Parcelable {

private int productId;
private int productImage;
private String productTitle;
private String productPrice;

public Product() {
}

public int getProductImage() {
return productImage;
}

public void setProductImage(int productImage) {
this.productImage = productImage;
}

public String getProductTitle() {
return productTitle;
}

public void setProductTitle(String productTitle) {
this.productTitle = productTitle;
}

public String getProductPrice() {
return productPrice;
}

public void setProductPrice(String productPrice) {
this.productPrice = productPrice;
}

public int getProductId() {
return productId;
}

public void setProductId(int productId) {
this.productId = productId;
}

// Parcelling part
public Product(Parcel in){
this.productTitle = in.readString();
this.productPrice = in.readString();
this.productId = in.readInt();
this.productImage = in.readInt();
}


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

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.productId);
dest.writeInt(this.productImage);
dest.writeString(this.productTitle);
dest.writeString(this.productPrice);
}

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

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


I use typedarray to get image resources.

private void getProductResources() {
typedArrayImages = getActivity().getResources().obtainTypedArray(R.array.prod_images);
prodTitles = getActivity().getResources().getStringArray(R.array.prod_titles);
prodPrices = getActivity().getResources().getStringArray(R.array.prod_prices);
}

private void getProductList() {
for (int i = 0; i < 4; i++) {
int rand_index = random.nextInt(4);
Product product = new Product();
product.setProductImage(typedArrayImages.getResourceId(rand_index, -1));
product.setProductPrice(prodPrices[rand_index]);
product.setProductTitle(prodTitles[rand_index]);
product.setProductId(prodIds[rand_index]);
this.product.add(product);
}
typedArrayImages.recycle();
mainPageAdapter.notifyDataSetChanged();
}


I click image on recyclerview to get another activity with parcelable object.

mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), mRecyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
if(position != 0){
Intent i = new Intent();
Bundle b = new Bundle();
b.putParcelable("Product", product.get(position - 1));
i.putExtras(b);
i.setClass(getActivity(), ProductActivity.class);
Log.i("PRODUCT", product.get(position - 1).getProductImage() + "");
startActivity(i);
}
}


I have a ResourceNotFoundException on set image resource. I can log resource images before and after clicking the image. Image resources changes.

productTitle.setText(product.getProductTitle());
productCost.setText(product.getProductPrice());
//Different image resources
Log.i("PRODUCT", product.getProductImage() + "");
//ResourcesNotFoundExceptions
productImg.setImageResource(product.getProductImage());

Answer

You have to read and write in the same order.

You wrote two ints, then two strings

dest.writeInt(this.productId);
dest.writeInt(this.productImage);
dest.writeString(this.productTitle);
dest.writeString(this.productPrice);

But you read two strings, and then two ints

this.productTitle = in.readString();
this.productPrice = in.readString();
this.productId = in.readInt();
this.productImage = in.readInt();
Comments