So serialisieren Sie den Nullwert bei Verwendung der Parcelable-Schnittstelle

Lesezeit: 4 Minuten

In Bezug auf mein Codebeispiel unten, was soll ich tun, wenn eine Locable-Variable null ist? Wenn beispielsweise l.getZoom() null zurückgibt, habe ich NullPointerException erhalten.

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

}

Vielen Dank!

  • Es scheint, dass NPE das Ergebnis von Auto-Unboxing ist. Wahrscheinlich sollte ich einfach nach Nullwert suchen und ihn auf 0 setzen?

    – igor.beslic

    5. Mai 2011 um 23:26 Uhr

  • Wenn Zoom Werte von 0+ hat, sollten Sie erwägen, null als -1 darzustellen

    – JAL

    5. Mai 2011 um 23:29 Uhr

  • Im Moment mache ich ähnliches, wenn Werte NULL sind, schreibe ich einige Werte wie -1 oder eine leere Zeichenfolge, die ich während der Deserialisierung auf NULL setze. Hässlich … Ich würde mich freuen, wenn jemand bestätigen kann, dass dies der richtige Weg ist. Ich wäre mit meinem Code zufriedener.

    – igor.beslic

    25. Mai 2011 um 10:10 Uhr

  • Nun, Primitive haben kein Konzept von null (oder objektivem C nil). Als generische Lösung frage ich mich, ob Sie Paare von Primitives senden können, um ein Objekt darzustellen, sagen Sie Int für int, zuerst ein boolescher Wert isNull und dann das primitive int, mit dem Sie Integer erstellen können ( int) oder Integer(null).

    – JAL

    25. Mai 2011 um 22:17 Uhr

Sie können verwenden Parcel.writeValue zum Marshallen eines generischen Objekts mit Nullwert.

  • und um den Wert zurückzulesen… s = (String) in.readValue(String.class.getClassLoader());

    – Sofi Software LLC

    10. Januar 2013 um 20:08 Uhr


  • @SofiSoftwareLLC Wenn Sie sich den Quellcode von packet.readValue ansehen, benötigen Sie nur einen Klassenlader für die Typen Map, Parcelable, ArrayList, Object[] und Paketfähig[]. Für andere Typen können Sie null für den Classloader übergeben. github.com/android/platform_frameworks_base/blob/…

    – miguel

    4. Februar 2015 um 18:52 Uhr


  • Sollte mit der Kommentarintegration von @SofiSoftwareLLC akzeptiert werden

    – ArteFact

    22. März 2019 um 13:52 Uhr

Ich benutze eine Parcelable Klasse, die hat Integer und Boolean Felder, und diese Felder können null sein.

Ich hatte Probleme mit dem Generikum Parcel.writeValue Methode, besonders wenn ich versuchte, es über auszulesen Parcel.readValue. Ich habe immer wieder eine Laufzeitausnahme erhalten, die besagte, dass der Typ des parzellierten Objekts nicht ermittelt werden konnte.

Letztendlich konnte ich das Problem mit lösen Parcel.writeSerializable und Parcel.readSerializable mit einer Art Besetzung, als beides Integer und Boolean Implementieren Sie die Serializable-Schnittstelle. Die Lese- und Schreibmethoden behandeln null Werte für Sie.

  • Ja, serialisierbar mit Besetzung funktioniert wie ein Zauber.

    – arenaq

    5. Februar 2019 um 8:29 Uhr

Dies ist die Lösung, die ich gefunden habe, um Zeichenfolgen sicher zu schreiben:

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

  • Ich hatte einige Probleme damit, nachdem ich Ihren Code kopiert und eingefügt hatte, ohne zu bemerken, dass ich in readStringFromParcel() die 1 in Byte umwandeln musste, bevor ich sie mit p.readByte() verglich. Am Ende entschied ich mich für “p.writeInt((s != null ? 1 : 0));” und “boolean isPresent = p.readInt() == 1;”

    – Matt

    21. April 2013 um 17:53 Uhr

  • Sie sollten die Zeichenfolge mit der Zeile schreiben p.writeString(s) nur wenn es nicht null ist; Andernfalls erhalten Sie in dieser Zeile eine NullPointerException.

    – Preis

    18. Juli 2014 um 6:13 Uhr


  • Wenn Sie verwenden p.writeParcelable Anstatt von p.writeString Sie erhalten nicht sofort eine NullPointerException, sondern später nur eine schattige ClassCastException, die durch die falsch ausgerichteten Lese- und Schreibsequenzen verursacht wird. Sie sollten das Objekt nur schreiben, wenn es nicht null ist.

    – Roland

    21. Februar 2018 um 16:21 Uhr

Die meisten Serialisierungscodes, die ich gesehen habe, verwenden entweder Flags, um das Vorhandensein/Fehlen eines Werts anzuzeigen, ODER stellen dem Wert ein Zählfeld voran (z. B. beim Schreiben von Arrays), wobei das Zählfeld nur auf Null gesetzt wird, wenn der Wert dies nicht tut. gibt es überhaupt nicht.

Die Untersuchung des Quellcodes der Android-Kernklassen zeigt Code wie diesen (aus der Message-Klasse):

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

oder dies (aus der Intent-Klasse):

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

Mein Vorschlag: Wenn es in Ihrem Code keinen funktionalen Unterschied zwischen “zoom == null” und “zoom == 0” gibt, würde ich einfach zoom als primitives deklarieren (int Anstatt von Integer) ODER initialisieren Sie es im Konstruktor auf Null und stellen Sie sicher, dass Sie es niemals auf Null setzen (dann können Sie garantieren, dass es niemals Null sein wird, und Sie müssen keinen speziellen Code hinzufügen, um dies in Ihren Serialisierungs-/Deserialisierungsmethoden zu behandeln ).

1211730cookie-checkSo serialisieren Sie den Nullwert bei Verwendung der Parcelable-Schnittstelle

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy