You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android技术问题:无法将自定义对象传入Intent

解决自定义对象无法添加到Intent的问题

你遇到的问题核心是自定义对象默认不能直接放入Intent——Intent只支持传递实现了序列化接口的对象。Android里有两种常用的序列化方案:Serializable(简单易实现)和Parcelable(Android官方推荐,效率更高),下面分别给你详细步骤,顺便帮你修正代码里的一个小错误。

一、先修正你代码里的明显错误

你的代码里这一行会抛出ClassCastException

itemList.setItem((List<Item>) item);

你不能把单个Item对象强转成List<Item>,正确的写法应该是先把item加入列表,再传给ItemList

// 创建列表并添加item
List<Item> itemListData = new ArrayList<>();
itemListData.add(item);
// 假设ItemList有对应的setter方法(比如setItems)
itemList.setItems(itemListData);

二、方案1:使用Serializable接口(快速实现)

这个方案代码改动最小,只需要让所有自定义类实现Serializable接口即可。

步骤1:让自定义类实现Serializable

修改ItemItemListInvoice类,添加implements Serializable

// Item类
public class Item implements Serializable {
    // 你的成员变量、getter/setter、构造方法都不用改
}

// ItemList类
public class ItemList implements Serializable {
    private List<Item> items; // 修正变量名更合理
    // getter/setter、构造方法
}

// Invoice类
public class Invoice implements Serializable {
    // 你的成员变量、getter/setter、构造方法
}

注意:如果类里包含其他自定义对象,那这个对象也必须实现Serializable(比如ItemList里的List,只要Item实现了就没问题)。

步骤2:将对象放入Intent

修改你的Intent代码:

Intent intent = getIntent();
// 用putExtra传递,第一个参数是自定义的key(后面取的时候要用)
intent.putExtra("EXTRA_INVOICE", invoice);

步骤3:从Intent中取出对象

在接收这个Intent的页面(比如目标Activity)里,这样取出:

Invoice receivedInvoice = (Invoice) getIntent().getSerializableExtra("EXTRA_INVOICE");

三、方案2:使用Parcelable接口(Android推荐,效率更高)

这个方案需要写一些额外的代码,但性能更好,适合频繁传递对象的场景。

步骤1:让Item类实现Parcelable

public class Item implements Parcelable {
    private String name;
    private String description;
    private double quantity;
    private String taxName;
    private String taxRate;
    private double unitPrice;

    // 常规构造方法
    public Item() {}

    // 从Parcel读取数据的构造方法
    protected Item(Parcel in) {
        name = in.readString();
        description = in.readString();
        quantity = in.readDouble();
        taxName = in.readString();
        taxRate = in.readString();
        unitPrice = in.readDouble();
    }

    // 必须实现的CREATOR
    public static final Creator<Item> CREATOR = new Creator<Item>() {
        @Override
        public Item createFromParcel(Parcel in) {
            return new Item(in);
        }

        @Override
        public Item[] newArray(int size) {
            return new Item[size];
        }
    };

    // 重写Parcelable的方法
    @Override
    public int describeContents() {
        return 0; // 几乎所有情况都返回0
    }

    // 将数据写入Parcel
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(description);
        dest.writeDouble(quantity);
        dest.writeString(taxName);
        dest.writeString(taxRate);
        dest.writeDouble(unitPrice);
    }

    // 你的getter/setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    // 其他getter/setter...
}

步骤2:让ItemList类实现Parcelable

public class ItemList implements Parcelable {
    private List<Item> items;

    public ItemList() {}

    protected ItemList(Parcel in) {
        // 读取TypedList,需要传入Item的CREATOR
        items = in.createTypedArrayList(Item.CREATOR);
    }

    public static final Creator<ItemList> CREATOR = new Creator<ItemList>() {
        @Override
        public ItemList createFromParcel(Parcel in) {
            return new ItemList(in);
        }

        @Override
        public ItemList[] newArray(int size) {
            return new ItemList[size];
        }
    };

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 写入TypedList
        dest.writeTypedList(items);
    }

    // getter/setter
    public List<Item> getItems() { return items; }
    public void setItems(List<Item> items) { this.items = items; }
}

步骤3:让Invoice类实现Parcelable

public class Invoice implements Parcelable {
    private String due;
    private String status; // 对应你代码里的"0",建议给个有意义的变量名
    private String currency;
    private String senderEmail;
    private String payerEmail;
    private String invoiceNumber;
    private ItemList itemList;

    public Invoice(String due, String status, String currency, String senderEmail, String payerEmail, String invoiceNumber, ItemList itemList) {
        this.due = due;
        this.status = status;
        this.currency = currency;
        this.senderEmail = senderEmail;
        this.payerEmail = payerEmail;
        this.invoiceNumber = invoiceNumber;
        this.itemList = itemList;
    }

    protected Invoice(Parcel in) {
        due = in.readString();
        status = in.readString();
        currency = in.readString();
        senderEmail = in.readString();
        payerEmail = in.readString();
        invoiceNumber = in.readString();
        // 读取Parcelable对象,需要传入类加载器
        itemList = in.readParcelable(ItemList.class.getClassLoader());
    }

    public static final Creator<Invoice> CREATOR = new Creator<Invoice>() {
        @Override
        public Invoice createFromParcel(Parcel in) {
            return new Invoice(in);
        }

        @Override
        public Invoice[] newArray(int size) {
            return new Invoice[size];
        }
    };

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(due);
        dest.writeString(status);
        dest.writeString(currency);
        dest.writeString(senderEmail);
        dest.writeString(payerEmail);
        dest.writeString(invoiceNumber);
        // 写入Parcelable对象
        dest.writeParcelable(itemList, flags);
    }

    // 你的getter/setter方法
}

步骤4:传递和取出对象

放入Intent:

Intent intent = getIntent();
intent.putExtra("EXTRA_INVOICE", invoice);

取出对象(Android 11及以下):

Invoice receivedInvoice = getIntent().getParcelableExtra("EXTRA_INVOICE");

取出对象(Android 12+,需要指定类):

Invoice receivedInvoice = getIntent().getParcelableExtra("EXTRA_INVOICE", Invoice.class);

两种方案对比

  • Serializable:代码改动极小,适合快速实现,但序列化/反序列化效率较低,适合简单对象或不频繁传递的场景。
  • Parcelable:需要写额外代码,但性能远高于Serializable,是Android官方推荐的跨组件传递对象的方式。

内容的提问来源于stack exchange,提问作者willpittman432

火山引擎 最新活动