Search code examples
androidandroid-activityandroid-resourcesparcelable

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());

Solution

  • 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();