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!
Sie können verwenden Parcel.writeValue
zum Marshallen eines generischen Objekts mit Nullwert.
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.
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;
}
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 ).
12117300cookie-checkSo serialisieren Sie den Nullwert bei Verwendung der Parcelable-Schnittstelleyes
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