2012-09-02 22 views
49

Tôi có một lớp mà thực hiện Parcelable giao diện:Viết một lớp con của Parcelable khác Parcel

class A implements Parcelable { 

} 

Tôi có một lớp B có chứa một đối tượng A như là một biến ví dụ. Trong writeToPacel bên trong lớp B, tôi muốn viết đối tượng B đến Parcel:

class B implements Parcelable{ 

    public void writeToParcel(Parcel dest, int flags) { 
     dest.write ??? 
    } 
} 

Làm thế nào tôi có thể viết và đọc nó?

+0

Đâu là 'Một object' bên B? – iTurki

Trả lời

143
class B implements Parcelable{ 
//lets assume you have A as a data member 

A obj; 
public void writeToParcel(Parcel dest, int flags) { 

     dest.writeParcelable(obj , flags); 

    } 
} 

nếu bạn muốn đọc nó sử dụng này

obj = in.readParcelable(A.class.getClassLoader()); 
+0

Tôi hữu ích mã này .... !!!!!!!!!!!!!! –

+5

Không cần đúc :) – pablisco

+4

Bạn thậm chí có thể chính xác hơn: 'obj = (A) in. readParcelable (A.class.getClassLoader());' – caw

2

Dòng:

obj = (A)in.readParcelable(A.class.getClassLoader()); 

nên thay đổi để:

obj = (A)in.readParcelable(B.class.getClassLoader()); 

tôi gặp phải vấn đề tương tự và đã làm một số tìm kiếm của Google, nhiều trang web hoặc hướng dẫn đề xuất chúng tôi sử dụng A.class.getClassLoader() vì chúng tôi đang truyền sang A, nhưng thực sự nó là BÀI VIẾT bởi vì bạn sẽ nhận được một giá trị null, chúng tôi phải sử dụng B.class.getClassLoader()codes are INSIDE class B. Tôi chỉ không biết tại sao nhưng nó có thể có được một đối tượng chính xác theo cách này.

Chào mừng bạn đến nhận xét và xác minh !!

10

Một cách tốt hơn để xử lý này mà tránh phản xạ sẽ được chỉ cần gọi tác giả tĩnh trong các loại mục tiêu như thế này:

this.amazingObject = AmazingObject.CREATOR.createFromParcel(in); 

và ghi nó vào Parcelable sử dụng this.amazingObject.writeToParcel(Parcel, int)

Bên trong, khi gọi readParcelable(ClassLoader) điều này xảy ra:

public final <T extends Parcelable> T readParcelable(ClassLoader loader) { 
    Parcelable.Creator<T> creator = readParcelableCreator(loader); 
    if (creator == null) { 
     return null; 
    } 
    if (creator instanceof Parcelable.ClassLoaderCreator<?>) { 
     return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader); 
    } 
    return creator.createFromParcel(this); 
} 

Như bạn có thể thấy lời gọi cuối cùng của phương thức đó là j ust gọi đúng Creator nhưng bên trong readParcelableCreator có rất nhiều phản xạ mà chúng ta có thể tránh bằng cách chỉ cần gọi trực tiếp. cuộc gọi

Tiện ích này có thể hữu ích:

import android.os.Parcel; 
import android.os.Parcelable; 

public class Parcels { 

    public static void writeBoolean(Parcel dest, Boolean value) { 
     dest.writeByte((byte) (value != null && value ? 1 : 0)); 
    } 

    public static Boolean readBoolean(Parcel in){ 
     return in.readByte() != 0; 
    } 

    public static void writeParcelable(Parcel dest, int flags, Parcelable parcelable) { 
     writeBoolean(dest, parcelable == null); 
     if (parcelable != null) { 
      parcelable.writeToParcel(dest, flags); 
     } 
    } 

    public static <T extends Parcelable> T readParcelable(Parcel in, Parcelable.Creator<T> creator) { 
     boolean isNull = readBoolean(in); 
     return isNull ? null : creator.createFromParcel(in); 
    } 

} 
+1

Nó ném một ngoại lệ khi đối tượng là null, trong khi '' readParcelable'' xử lý tình huống này một cách chính xác – dragoon

+0

@dragoon Ngoại lệ bạn nhận được là gì? – pablisco

+0

Tôi sẽ sử dụng Parcel Util của riêng mình nhưng cảm ơn vì nguồn cảm hứng! – Juancho

Các vấn đề liên quan