在实现Parcelable时使用Float而不是float(Primitive类型)

时间:2017-08-16 07:26:01

标签: android parcelable

要求:找出price是否为空。由于原始浮点数据类型无法检查为null,因为它始终为0.0,因此我选择使用Float,因为它可以检查为null。

public class QOptions implements Parcelable {
    public String text;
    public Float price;
}

protected QOptions(Parcel in) {
    text = in.readString();
    unit_price = in.readFloat();
}

@Override
public void writeToParcel(Parcel parcel, int i) {
    parcel.writeString(this.text);
    parcel.writeFloat(this.price);
}

但是,由于该类还实现了ParcelablewriteToParcel崩溃时出现以下异常:

  

尝试在空对象引用上调用虚方法'float java.lang.Float.floatValue()'

例外情况指向这一行:

  

parcel.writeFloat(this.price);

如何将Float数据类型与writeToParcel一起使用而不会导致异常?或者有更好的方法来完成我的要求吗?如果价格为空,我只需要价格为空。

3 个答案:

答案 0 :(得分:4)

您可以通过以下方式处理。

//Depending on where this code is, you may need to find your UpdatePanel control.
Private Sub RaiseErrorMessageModal(errorMessage As String)
    lblmodalErrorMessage.Text = errorMessage
    UpdatePanel123.Update()
    RegisterModalPopup(modalErrorMessage.ClientID)
End Sub

读取float的值 -

@Override
public void writeToParcel(Parcel dest, int flags) {
    if (price == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeFloat(price);
    }
}

答案 1 :(得分:1)

十进制类型具有许多特殊值:NaN,负数和正数无穷大。您可以使用这些值来表示Requestly: Redirect Url, Modify Headers

null

阅读时:

if (price == null) {
  parcel.writeFloat(Float.NaN);
} else {
  parcel.writeFloat(price);
}

NaN的意思是“不是一个数字”,所以它非常适合于序列化事物。

与@Kapil G提供的解决方案不同,此方法不会浪费额外的4个字节用于可空性标记(由于性能原因,每次调用float p = parcel.readFloat(); if (Float.isNaN(p)) { price = null; } else { price = p; } 实际上在Parcal中存储了整个writeByte()

答案 2 :(得分:0)

对于parceling Float,这两个方法调用是安全的:

dest.writeValue(price);
in.readValue(null);

对于任何parcelable类型,你可以使用它:

SomeType value; // ...
dest.writeValue(value);
in.readValue(SomeType.class.getClassLoader());

可以找到parcelable类型列表in Parcel docs

赞成

  • 每次读写一行。
  • 您不必担心在分割和取消分配时手动区分nullfloat。它在内部为你完成。
  • 可以表达NaN和无穷大。

如何运作

以下是Parcel源代码的相关部分:

public class Parcel {
    private static final int VAL_NULL = -1;
    private static final int VAL_FLOAT = 7;

    public final void writeValue(Object v) {
        if (v == null) {
            writeInt(VAL_NULL);
        } else if (v instanceof Float) {
            writeInt(VAL_FLOAT);
            writeFloat((Float) v);
        } // ...
    }

    public final Object readValue(ClassLoader loader) {
        int type = readInt();

        switch (type) {
            case VAL_NULL:
                return null;

            case VAL_FLOAT:
                return readFloat();

            // ...
        }
    }
}

请注意,对于Float(以及其他已装箱的基元),loader参数未使用,因此您可以传递null

在此处浏览来源:https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/Parcel.java