Android 中带有枚举的 Parcelable 对象

Parcelable object with enums in Android

在一个 android 项目中,我有一个包含这些字段的 class:

public class TransactionHistoryDetail1 implements Parcelable, DatabaseEnabled{

    private long id;
    private static final String TABLE_NAME = "TransactionHistoryDetail";
    private static final String EMPTY_STRING = "";

    @XmlElement(name = "TxUd", required = true)
    private String TxUd;
    @XmlElement(name = "TxLclDtTm", required = true)
    private Date TxLclDtTm;
    @XmlElement(name = "CcyCd")
    private CurrencyCode CcyCd;
    @XmlElement(name = "Amt")
    private BigDecimal Amt;
    @XmlElement(name = "PmttpCd", required = true)
    private PaymentTypeCode PmttpCd;
    @XmlElement(name = "OprtnCd", required = true)
    private OperationCode OprtnCd;
    @XmlElement(name = "AppLabltpCd", required = true)
    private AppLabelTypeCode AppLabltpCd;
    @XmlElement(name = "PdSrl")
    private String PdSrl;
    @XmlElement(name = "PdBrndDsc")
    private String PdBrndDsc;
    @XmlElement(name = "UsrEml")
    private String UsrEml;
    @XmlElement(name = "CstmrAdr")
    private String CstmrAdr;
    @XmlElement(name = "TxDtlDsc")
    private String TxDtlDsc;
    @XmlElement(name = "TxRltdInd")
    private boolean TxRltdInd;
    @XmlElement(name = "TxSttsCd", required = true)
    private TransactionStatusCode TxSttsCd;
    @XmlElement(name = "UpdtDt", required = true)
    private Date UpdtDt;
...
}

我正在尝试将此 class 的对象作为 Parcelables 写入和读取,但我不确定如何写入和读取枚举。

我的 writeToParcel 方法如下所示:

   @Override
public void writeToParcel(Parcel dest, int flags) {

    SimpleDateFormat sdf = new SimpleDateFormat(JsonBuilder.DateFormat);

    dest.writeLong(id);
    dest.writeDouble(Amt.doubleValue());
    dest.writeString(PdSrl);
    dest.writeString(PdBrndDsc);
    dest.writeString(TxUd);
    dest.writeString(PdSrl);
    dest.writeString(UsrEml);
    dest.writeString(CstmrAdr);
    dest.writeString(TxDtlDsc);
    dest.writeString((CcyCd == null) ? "" : CcyCd.name());
    dest.writeString((PmttpCd == null) ? "" : PmttpCd.name());
    dest.writeString((OprtnCd == null) ? "" : OprtnCd.name());
    dest.writeString((AppLabltpCd == null) ? "" : AppLabltpCd.name());
    dest.writeString(sdf.format(TxLclDtTm));
    dest.writeString(sdf.format(UpdtDt));
    dest.writeByte((byte) (TxRltdInd ? 1 : 0));
}

我的 Parcel 构造器看起来像这样

private TransactionHistoryDe​​tail1(包裹在){

    SimpleDateFormat sdf = new SimpleDateFormat(JsonBuilder.DateFormat);
    try {
        TxLclDtTm = sdf.parse(in.readString());
        UpdtDt = sdf.parse(in.readString());
    } catch (ParseException e) {
        e.printStackTrace();
    }
    id = in.readLong();
    TxUd = in.readString();
    PdSrl = in.readString();
    PdBrndDsc = in.readString();
    UsrEml = in.readString();
    CstmrAdr = in.readString();
    TxDtlDsc = in.readString();
    TxRltdInd = in.readByte() != 0;
    Amt = new BigDecimal(in.readDouble());
    CcyCd = CurrencyCode.valueOf(in.readString());
    PmttpCd = PaymentTypeCode.valueOf(in.readString());
    OprtnCd = OperationCode.valueOf(in.readString());
    AppLabltpCd = AppLabelTypeCode.valueOf(in.readString());
    TxSttsCd = TransactionStatusCode.fromValue(in.readString());

}

writeToParcel 我相信它运行良好,但构造函数在 "CcyCd" 行崩溃。

我的 CurrencyCode class 是一个枚举(PaymentTypeCode、OperationCode 和 AppLabelTypeCode 也是),如下所示:

@XmlType(name = "CurrencyCode")
@XmlEnum
public enum CurrencyCode {

    EUR;

    public String value() {
        return name();
    }

    public static CurrencyCode fromValue(String v) {
        return valueOf(v);
    }
}

还有其他方法可以处理 Parcelables 中的枚举吗?

我得到的异常是这样的:

java.lang.RuntimeException: Unable to start activity ComponentInfo{package/package.activities.ChildActivity}: java.lang.IllegalArgumentException: No enum constant package.data.apiClasses.CurrencyCode.��EUR����CASH������CLS����APP����2017-04-10T09:07:52.525Z������2017-04-10T09:07:52.528Z����������CHILD_12345������?

首先,您应该按照您写入的 确切顺序 Parcel 读取。由于 Parcel 只是按顺序写入和读取数据,而不是实际序列化数据,因此您必须保持读取和写入,否则您将读取错误的值并出现错误..

最好把Enum当成int,这样写到parcel

dest.writeInt(this.CcyCd == null ? -1 : this.CurrencyCode.ordinal());

并像这样阅读它们:

int tmpCurrencyCode = in.readInt();
this.CcyCd = tmpCurrencyCode == -1 ? null : CurrencyCode.values()[tmpMState];

P.S:此代码也检查空值 ^^

我在解析 Nullable Enum 时遇到问题。如果是这种情况,请查看此处