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

时间:2011-05-05 23:09:57

标签: android nullpointerexception 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 个答案:

答案 0 :(得分:101)

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

答案 1 :(得分:18)

我使用的import random monsters = [("Goblin", 1), ("Troll", 3), ("Bear", 2), ("Giant Spider", 1), ("Bandit", 1), ("Wolf", 1), ("Homeless Man", 1), ("Goblin Chief", 3)] def spawnMonster(): enemy, DMG = random.choice(monsters) print(enemy) output = "A " + enemy + " comes out of the bushes." spawnMonster() print(output) 类也有ParcelableInteger字段,这些字段可以为空。

我在使用通用Boolean方法时遇到了问题,尤其是当我尝试通过Parcel.writeValue将其读回时。我一直得到一个运行时异常,说它无法弄清楚所包含对象的类型。

最终,我能够通过Parcel.readValueParcel.writeSerializable使用类型转换来解决问题,因为Parcel.readSerializableInteger都实现了Serializable接口。 read和write方法为您处理Boolean值。

答案 2 :(得分:14)

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

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

答案 3 :(得分:13)

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

检查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”之间没有功能差异,那么我只会将缩放声明为基元({{ 1}}而不是int)或者在构造函数中将它初始化为零,并确保你永远不会将它设置为null(然后你可以保证它永远不会为null,你不必添加特殊代码在序列化/反序列化方法中处理它。)