使用 Parcelable 接口时如何序列化 null 值

发布于 2024-11-05 12:29:33 字数 565 浏览 0 评论 0原文

关于我的代码示例,如果一个 Locable 的变量为空,我该怎么办?例如,现在如果 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());
    }

}

谢谢!

regarding my code example down, what shold I do if one Locable's variables is null? In example, now if l.getZoom() returns null, I got 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());
    }

}

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花落人断肠 2024-11-12 12:29:33

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

You can use Parcel.writeValue for marshalling generic object with null value.

软甜啾 2024-11-12 12:29:33

我使用的 Parcelable 类也具有 IntegerBoolean 字段,并且这些字段可以为 null。

我在使用通用 Parcel.writeValue 方法时遇到了麻烦,特别是当我尝试通过 Parcel.readValue 读回它时。我不断收到运行时异常,表示无法确定包裹对象的类型。

最终,我能够通过使用 Parcel.writeSerializedParcel.readSerialized 以及类型转换来解决问题,因为 IntegerBoolean 实现 Serialized 接口。读取和写入方法为您处理 null 值。

I'm using a Parcelable class that has Integer and Boolean fields as well, and those fields can be null.

I had trouble using the generic Parcel.writeValue method, particularly when I was trying to read it back out via Parcel.readValue. I kept getting a runtime exception that said it couldn't figure out the type of the parceled object.

Ultimately, I was able to solve the problem by using Parcel.writeSerializable and Parcel.readSerializable with a type cast, as both Integer and Boolean implement the Serializable interface. The read and write methods handle null values for you.

滿滿的愛 2024-11-12 12:29:33

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

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

This is the solution I came up with to write strings safely:

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;
}
一身软味 2024-11-12 12:29:33

我见过的大多数序列化代码都使用标志来指示值的存在/不存在,或者在值之前添加计数字段(例如,在写入数组时),其中如果值不存在,则计数字段仅设置为零根本不存在。

检查 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,并且您不必添加特殊代码来在序列化/反序列化方法中处理该问题)。

Most serialization code that I've seen uses either flags to indicate the presence/absence of a value OR precedes the value with a count field (for example, when writing arrays) where the count field is just set to zero if the value doesn't exist at all.

Examining the source code of Android core classes reveals code like this (from Message class):

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

or this (from Intent class):

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

My suggestion: In your code, if there is no functional difference between "zoom == null" and "zoom == 0", then I would just declare zoom as a primitive (int instead of Integer) OR initialize it to zero in the constructor and ensure that you never set it to null (then you can be guaranteed that it will never be null and you won't have to add special code to deal with that in your serialization/deserialization methods).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文