android-如何在使用Parcelable时序列化空值

关于我的代码示例,如果一个Locable的变量为null,该怎么办? 例如,现在如果l.getZoom()返回null,则得到NullPointerException。

@Override
public void writeToParcel(Parcel parcel, int arg1) {
    parcel.writeInt(count);
    for(Locable l:locableArr){
        parcel.writeInt(l.getOriginId());
        parcel.writeInt(l.getLocableType());
        parcel.writeInt(l.getZoom());
        parcel.writeDouble(l.getLatituda());
        parcel.writeDouble(l.getLongituda());
        parcel.writeString(l.getTitle());
        parcel.writeString(l.getSnipet());
    }

}

谢谢!

4个解决方案
100 votes

您可以使用Parcel.writeValue来编组具有空值的通用对象。

artch answered 2019-10-09T14:25:18Z
18 votes

我正在使用具有IntegerParcel.writeSerializable字段的Parcelable类,这些字段可以为空。

我在使用通用2561770709202202764800方法时遇到了麻烦,尤其是当我尝试通过Parcel.readSerializable801读回它时。我一直收到运行时异常消息,说它无法弄清包裹对象的类型。

最终,我能够通过将Parcel.writeSerializableParcel.readSerializable与类型转换一起使用来解决该问题,因为IntegerBoolean都实现了Serializable接口。 读写方法可以为您处理null的值。

Justin Hong answered 2019-10-09T14:26:04Z
14 votes

这是我想出的安全编写字符串的解决方案:

private void writeStringToParcel(Parcel p, String s) {
    p.writeByte((byte)(s != null ? 1 : 0));
    p.writeString(s);
}

private String readStringFromParcel(Parcel p) {
    boolean isPresent = p.readByte() == 1;
    return isPresent ? p.readString() : null;
}
Felipe Lima answered 2019-10-09T14:26:42Z
13 votes

我见过的大多数序列化代码都使用两个标志来指示值的存在/不存在,或者在值前加上一个计数字段(例如,在编写数组时),如果该值不等于,则计数字段仅设置为零。 根本不存在。

检查Android核心类的源代码会发现以下代码(来自Message类):

    if (obj != null) {
        try {
            Parcelable p = (Parcelable)obj;
            dest.writeInt(1);
            dest.writeParcelable(p, flags);
        } catch (ClassCastException e) {
            throw new RuntimeException(
                "Can't marshal non-Parcelable objects across processes.");
        }
    } else {
        dest.writeInt(0);
    }

或这个(来自Intent类):

    if (mCategories != null) {
        out.writeInt(mCategories.size());
        for (String category : mCategories) {
            out.writeString(category);
        }
    } else {
        out.writeInt(0);
    }

我的建议:在您的代码中,如果“ zoom == null”和“ zoom == 0”之间没有功能上的区别,那么我只需要将zoom声明为原始变量(int而不是Integer),或者将其初始化为零 构造函数,并确保您永远不要将其设置为null(这样就可以保证它永远不会为null,并且您不必在序列化/反序列化方法中添加特殊代码来处理它)。

David Wasser answered 2019-10-09T14:27:42Z
translate from https://stackoverflow.com:/questions/5905105/how-to-serialize-null-value-when-using-parcelable-interface