How to serialize null value when using Parcelable interface

前端 未结 4 597
抹茶落季
抹茶落季 2020-12-08 09:35

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.



        
相关标签:
4条回答
  • 2020-12-08 09:49

    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.

    0 讨论(0)
  • 2020-12-08 09:58

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

    0 讨论(0)
  • 2020-12-08 09:58

    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).

    0 讨论(0)
  • 2020-12-08 10:01

    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;
    }
    
    0 讨论(0)
提交回复
热议问题