2013-01-17 29 views
10

Gần đây tôi đã nhìn thấy một thực tế rất ngu ngốc (ít nhất là từ quan điểm của tôi) trong Androids Parcel lớp.Làm thế nào để sử dụng writeStringArray() và readStringArray() trong một bưu kiện

Giả sử tôi có một lớp đơn giản như thế này

class Foo implements Parcelable{ 

    private String[] bars; 
    //other members 

    public in describeContents(){ 
     return 0; 
    } 

    public void writeToParcel(Parcel dest, int flags){ 

     dest.writeStringArray(bars); 
     //parcel others 
    } 

    private Foo(Parcel source){ 
     source.readStringArray(bars); 
     //unparcel other members 
    } 

    public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>(){ 

     public Foo createFromParcel(Parcel source){ 
      return new Foo(source); 
     } 

     public Foo[] newArray(int size){ 
      return new Foo[size]; 
     } 

    }; 
} 

Bây giờ, nếu tôi muốn Parcel một Object Foobars là null tôi thấy không có cách nào để phục hồi từ tình trạng này (exept bắt Exceptions tất nhiên) . Dưới đây là việc triển khai hai phương pháp này từ Parcel:

public final void writeStringArray(String[] val) { 
     if (val != null) { 
      int N = val.length; 
      writeInt(N); 
      for (int i=0; i<N; i++) { 
       writeString(val[i]); 
      } 
     } else { 
      writeInt(-1); 
     } 
    } 


    public final void readStringArray(String[] val) { 
     int N = readInt(); 
     if (N == val.length) { 
      for (int i=0; i<N; i++) { 
       val[i] = readString(); 
      } 
     } else { 
      throw new RuntimeException("bad array lengths"); 
     } 
    } 

Vì vậy, writeStringArray là tốt nếu tôi vượt qua bars không có giá trị. Nó chỉ viết -1 cho bưu kiện. Nhưng phương thức readStringArray được sử dụng như thế nào? Nếu tôi vượt qua bars bên trong (trong đó tất nhiên là null), tôi sẽ nhận được một NullPointerException từ val.length. Nếu tôi tạo ra bars trước khi nói như vậy bars = new String[???] Tôi không nhận được bất kỳ đầu mối nào lớn như thế. Nếu kích thước không khớp với những gì được viết bên trong, tôi nhận được một RuntimeException.

Tại sao readStringArray không biết kết quả của -1 được ghi trên đối tượng rỗng từ writeStringArray và chỉ trả về?

Cách duy nhất tôi thấy là để lưu kích thước của bars trước khi tôi gọi writeStringArray(String[]) khiến phương pháp này trở nên vô dụng. Nó cũng sẽ redundatly tiết kiệm kích thước của mảng hai lần (một lần cho tôi nhớ, lần thứ hai từ writeStringArray).

Có ai biết làm thế nào hai phương pháp này được cho là được sử dụng, vì không có java-doc cho chúng trên đầu trang?

Trả lời

28

Bạn nên sử dụng Parcel.createStringArray() trong trường hợp của mình.

Tôi không thể tưởng tượng một trường hợp sử dụng thích hợp cho Parcel.readStringArray(String[] val) nhưng để sử dụng nó, bạn phải biết kích thước chính xác của mảng và phân bổ theo cách thủ công.

+0

cảm ơn. không bao giờ nhận thấy các chức năng tạo * này. Tôi vẫn để câu hỏi này mở ra một chút, để ai đó có thể cho tôi một mục đích cho phương pháp xấu xí đó. –

4

Nó không thực sự rõ ràng từ tài liệu (thiếu) nhưng readStringArray() sẽ được sử dụng khi đối tượng đã biết cách tạo mảng chuỗi trước khi gọi hàm này; ví dụ khi nó được thống kê về mặt thống kê hoặc kích thước của nó được biết đến từ một giá trị đã đọc trước đó.

Điều bạn cần ở đây là gọi hàm createStringArray().