Android跨Activity传序列化数据至RecyclerView适配器报错求助
解决Android中传递序列化数据到RecyclerView适配器的问题
你遇到的错误核心原因是**ProductsItem类没有实现序列化接口**——虽然你在代码里把List<ProductsItem>强转成了Serializable,但如果列表里的元素本身不支持序列化,系统就会抛出无法marshal的异常。另外还有个明显的小问题:你在循环里每次都启动SearchActivity,这会导致多次重复打开页面,显然不是你想要的效果,应该把整个列表一次性传递。
下面是具体的解决步骤:
1. 让ProductsItem实现序列化接口
Android中推荐使用Parcelable(比Serializable更高效),当然也可以用Serializable,这里两种方式都给你:
方式一:实现Serializable接口
修改你的ProductsItem类,让它实现Serializable接口即可,不需要额外编写复杂代码:
public class ProductsItem implements Serializable { // 你的所有字段、getter和setter方法保持不变 }
方式二:实现Parcelable接口(Android推荐)
Parcelable是Android专属的序列化方式,性能更优。Android Studio可以自动生成相关代码:右键类内部 → Generate → Parcelable,示例代码如下:
public class ProductsItem implements Parcelable { // 你的所有字段,比如stock_division_id、cover_status等 protected ProductsItem(Parcel in) { // 按顺序读取Parcel中的字段,要和writeToParcel的顺序一致 stock_division_id = in.readString(); cover_status = in.readString(); listing_image_color_id = in.readString(); // ... 依次添加其他字段的读取逻辑 } public static final Creator<ProductsItem> CREATOR = new Creator<ProductsItem>() { @Override public ProductsItem createFromParcel(Parcel in) { return new ProductsItem(in); } @Override public ProductsItem[] newArray(int size) { return new ProductsItem[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // 按顺序写入字段到Parcel dest.writeString(stock_division_id); dest.writeString(cover_status); dest.writeString(listing_image_color_id); // ... 依次添加其他字段的写入逻辑 } // 你的getter和setter方法 }
2. 修正数据传递的代码
把循环里的Intent启动逻辑移出来,循环只用来显示Toast,最后一次性传递整个列表:
private void callApigetCategoryItems() { ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); Call<CategoryResponse> call = apiService.getCategoryResult(1); call.enqueue(new Callback<CategoryResponse>() { @Override public void onResponse(Call<CategoryResponse> call, Response<CategoryResponse> response) { List<ProductsItem> products = response.body().getData().getProducts(); // 循环显示每个商品的分类名称 for (int i = 0; i < products.size(); i++) { String stockCategoryName = products.get(i).getStockCategoryName(); Toast.makeText(HomeActivity.this, "" + stockCategoryName, Toast.LENGTH_SHORT).show(); } // 循环结束后,一次性传递整个列表到SearchActivity Intent intent = new Intent(getApplicationContext(), SearchActivity.class); // 如果用Serializable intent.putExtra("category", (Serializable) products); // 如果用Parcelable,需要转成ArrayList // intent.putParcelableArrayListExtra("category", new ArrayList<>(products)); startActivity(intent); } @Override public void onFailure(Call<CategoryResponse> call, Throwable t) { Toast.makeText(HomeActivity.this, "" + t.getMessage(), Toast.LENGTH_SHORT).show(); } }); }
3. 在SearchActivity中接收数据并传给适配器
根据你选择的序列化方式,对应接收数据:
如果用Serializable:
// 接收数据 List<ProductsItem> productsItemList = (List<ProductsItem>) getIntent().getSerializableExtra("category"); // 传给RecyclerView适配器 yourRecyclerViewAdapter.setData(productsItemList); yourRecyclerViewAdapter.notifyDataSetChanged();
如果用Parcelable:
// 接收数据 ArrayList<ProductsItem> productsItemList = getIntent().getParcelableArrayListExtra("category"); // 传给RecyclerView适配器 yourRecyclerViewAdapter.setData(productsItemList); yourRecyclerViewAdapter.notifyDataSetChanged();
额外注意事项
- 如果
ProductsItem中包含嵌套对象,这些嵌套对象也必须实现对应的序列化接口,否则依然会报错。 - 不要用Intent传递过大的数据,否则可能触发
TransactionTooLargeException。如果数据量很大,建议用ViewModel、全局单例或者本地数据库来存储和传递数据。
内容的提问来源于stack exchange,提问作者Abhishek S
相关产品推荐
相关产品推荐

