2011-05-05 16 views
51

kullanılırken boş değer nasıl serileştirilir, bir Locable değişkeninin boş olması durumunda ne yapacağım? Örneğin, l.getZoom() öğesi null değerini döndürürse, NullPointerException var.Kod örneğim ile ilgili Parcelable arabirimi

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

} 

Teşekkürler!

+0

NPE, Otomatik olarak açılır kutusunun bir sonucu olarak görünüyor. Muhtemelen boş değeri kontrol etmeli ve 0 olarak ayarlamalı mıyım? –

+0

Yakınlaştırmanın değerleri 0+ ise, null değerini 1 – JAL

+0

olarak göstermeyi düşünün Şimdi benzer bir şey yapıyorum Şimdilik, değerler NULL ise, serileştirme ayarı sırasında NULL olarak belirttiğim -1 veya boş dize gibi değerler yazıyorum. Çirkin ... Birinin bunu doğrulayabileceğini doğrulamak isterim. Bu benim kodumdan daha memnun olurum. –

cevap

13

Gördüğüm çoğu seri hale getirme kodu, değer OR'in varlığını/yokluğunu belirtmek için bir VEYA sayı alanıyla (örneğin, diziler yazılırken) önce değerden önce gelir. Değer hiç mevcut değil.

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

veya bu (Niyet sınıfından):

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

Benim öneri: olarak Android çekirdek sınıfların kaynak kodunu inceleyerek

(mesaj sınıfı), bu gibi kod ortaya kodunuz, "zoom == null" ve "zoom == 0" arasında hiçbir işlevsel fark yoksa, sadece bir ilkel olarak yakınlaştırmayı bildirir (yerine Integer) VEYA constructo'da sıfır olarak başlatır r ve asla null olarak ayarlamamış olduğunuzdan emin olun (daha sonra asla boş olmayacağından emin olabilirsiniz ve serileştirme/serileştirme yöntemlerinizle başa çıkmak için özel kod eklemeniz gerekmez).

91

Parcel.writeValue null değeriyle marshalling genel nesnesini kullanabilirsiniz.

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

ve değeri geri okumak için ... s = (String) in.readValue (String.class.getClassLoader()); –

+0

Harika! Teşekkür ederim. – tasomaniac

+2

@SofiSoftwareLLC parcel.readValue kaynak koduna bakarak sadece Map, Parcelable, ArrayList, Object [] ve Parcelable [] türleri için bir sınıf yükleyicisine ihtiyaç duyar. Diğer türler için classloader için null geçebilirsiniz. https: // github.com/android/platform_frameworks_base/blob/3bdbf644d61f46b531838558fabbd5b990fc4913/core/java/android/os/Parcel.java # L2002 – miguel

10

Bu güvenle dizeleri yazmak için geldi çözümdür.

Genel Parcel.writeValue yöntemini kullanarak, özellikle Parcel.readValue aracılığıyla geri okumaya çalıştığımda, sorun yaşadım. Parselli nesnenin türünü anlayamadığını söyleyen bir çalışma zamanı istisnası almaya devam ettim.

Sonuç olarak, her ikisi de Integer ve Boolean Serializable arayüzü uygularken, bir tür alçı ile Parcel.writeSerializable ve Parcel.readSerializable kullanarak sorunu çözmek mümkün oldu. Okuma ve yazma yöntemleri sizin için null değerlerini işliyor.

+0

Bunu kopyaladıktan ve kodunuzu yapıştırdıktan sonra bununla ilgili bazı problemlerim vardı, bunu readStringFromParcel() içinde gerçekleştirmem gerektiğini farketmem. P.readByte() ile karşılaştırmadan önce 1 byte. Sonunda "p.writeInt ((s! = Null? 1: 0));" ve "boolean isPresent = p.readInt() == 1;" – Matt

+3

Dizeyi, yalnızca null olmadığında "p.writeString (ler)" satırını kullanarak yazmalısınız; aksi halde bu satırda bir NullPointerException alırsınız. – Price

+0

Eğer 'p.writeString' yerine' p.writeParcelable' kullanıyorsanız, hemen bir NullPointerException alamayacaksınız, daha sonra yanlış hizalanmış okuma ve yazma dizilerinin neden olduğu bazı gölgeli ClassCastException. Yalnızca boş değilse nesneyi yazmalısınız. – Roland

11

Ben de Integer ve Boolean alanları içeren bir Parcelable sınıfını kullanıyorum ve bu alanları boş olabilir:

+0

Bu aslında çalışıyor. –

İlgili konular