【问题标题】:Parcelable object with enums in AndroidAndroid 中带有枚举的 Parcelable 对象
【发布时间】:2017-04-10 09:57:10
【问题描述】:

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

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;
...
}

我正在尝试将此类的对象作为 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(Parcel in) {

    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 类是一个枚举(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:无法启动活动 ComponentInfo{package/package.activities.ChildActivity}:java.lang.IllegalArgumentException:没有枚举常量 package.data.apiClasses.CurrencyCode.��EUR����CASH。 �����CLS����APP����2017-04-10T09:07:52.525Z������2017-04-10T09:07:52.528Z���������� �CHILD_12345������?

【问题讨论】:

    标签: android enums parcelable


    【解决方案1】:

    首先,您应该按照您写给它的确切顺序阅读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:这段代码也检查空值^^

    【讨论】:

    • 什么是 tmpMState?
    • 我猜它的 tmpCurrencyCode。在 in.readInt() 已经得到 0、101、24 等之后,我在 tmpCurrencyCode 中得到了一些奇怪的值。之后我在下面的行中得到一个异常 Unable to start activity ComponentInfo{package/package.activities.ChildActivity}: java.lang.ArrayIndexOutOfBoundsException: length=1;索引=24
    • 您在读写包裹时是否遵循顺序?您应该完全按照您写入包裹的顺序从包裹中读取,但在您的代码中您没有按顺序执行..
    • 啊,不知道,我试试
    【解决方案2】:

    我在解析 Nullable Enum 时遇到问题。如果这是您的情况,请查看此处 https://stackoverflow.com/a/58337932/5980046

    【讨论】:

      猜你喜欢
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多