2013-08-01 36 views
35

Tôi muốn marshall và unmarshall một Class mà thực hiện Parcelable đến/từ một mảng byte. Tôi cũng nhận thức được thực tế là đại diện Parcelable không ổn định và do đó không có nghĩa là lưu trữ lâu dài các trường hợp. Nhưng tôi có một trường hợp sử dụng, nơi tôi cần serialize một đối tượng và nó không phải là một showstopper nếu unmarshalling không thành công vì một sự thay đổi Android nội bộ. Ngoài ra, lớp đã triển khai giao diện Parcelable.Làm thế nào để marshall và unmarshall một Parcelable đến một mảng byte với sự giúp đỡ của bưu kiện?

Cho một lớp học MyClass implements Parcelable, làm thế nào tôi có thể (ab) sử dụng giao diện Parcelable để sắp xếp/không sửa lỗi?

Trả lời

97

Đầu tiên tạo ra một lớp helper ParcelableUtil.java:

public class ParcelableUtil {  
    public static byte[] marshall(Parcelable parceable) { 
     Parcel parcel = Parcel.obtain(); 
     parceable.writeToParcel(parcel, 0); 
     byte[] bytes = parcel.marshall(); 
     parcel.recycle(); 
     return bytes; 
    } 

    public static Parcel unmarshall(byte[] bytes) { 
     Parcel parcel = Parcel.obtain(); 
     parcel.unmarshall(bytes, 0, bytes.length); 
     parcel.setDataPosition(0); // This is extremely important! 
     return parcel; 
    } 

    public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) { 
     Parcel parcel = unmarshall(bytes); 
     T result = creator.createFromParcel(parcel); 
     parcel.recycle(); 
     return result; 
    } 
} 

Với sự giúp đỡ của lớp util ở trên, bạn có thể marshall/trường hợp unmarshall của lớp học của bạn MyClass implements Parcelable như vậy:

unmarshalling (với CREATOR)

byte[] bytes = … 
MyClass myclass = ParcelableUtil.unmarshall(bytes, MyClass.CREATOR); 

unmarshalling (không CREATOR)

byte[] bytes = … 
Parcel parcel = ParcelableUtil.unmarshall(bytes); 
MyClass myclass = new MyClass(parcel); // Or MyClass.CREATOR.createFromParcel(parcel). 

Marshalling

MyClass myclass = … 
byte[] bytes = ParcelableUtil.marshall(myclass); 
+4

'parcel.setDataPosition (0); // điều này cực kỳ quan trọng! 'điều này giúp tôi rất nhiều. thiếu tài liệu Android của điều này, thực sự là suck. –

+0

Cảm ơn bạn rất nhiều vì mẹo này. Thực hiện Parcelable (đó là cực kỳ dễ bị lỗi và bạn sẽ nhận được trường hợp ngoại lệ thời gian vô nghĩa và khách hàng tức giận nếu không được thực hiện đúng) là một PITA - Tôi tránh Parcelables trong mã của tôi hoàn toàn và tôi đang sử dụng Serializables. Trên điện thoại hiện đại, tốc độ trúng là khó nhận thấy. –

+1

Vấn đề duy nhất với cách tiếp cận này, tuy nhiên, là unmarshalling một lớp con của lớp thực hiện Parcelable sẽ không được đơn giản. Bạn sẽ cần phải chuyển thông tin bổ sung mà từ đó bạn có thể đánh giá đúng Creator để sử dụng. – bosphere

-3
public static byte[] pack(Parcelable parcelable) { 
    Parcel parcel = Parcel.obtain(); 
    parcelable.writeToParcel(parcel, 0); 
    byte[] bytes = parcel.marshall(); 
    parcel.recycle(); 
    return bytes; 
} 

public static <T> T unpack(byte[] bytes, Parcelable.Creator<T> creator) { 
    Parcel parcel = Parcel.obtain(); 
    parcel.unmarshall(bytes, 0, bytes.length); 
    parcel.setDataPosition(0); 
    return creator.createFromParcel(parcel); 
} 

MyObject myObject = unpack(new byte[]{/* bytes */}, MyObject.CREATOR); 
+2

Vui lòng cung cấp giải thích ngắn gọn về mã bạn đã đăng để dễ hiểu hơn cho OP. – Jatin