1. 程式人生 > >Android Parcelable 巢狀readParcelable

Android Parcelable 巢狀readParcelable

對於Android的自定義物件進行序列化,一般會選擇Parcelable,或者Serializable。
在Android中,由於在使用記憶體時,Parcelable類要比Serializable類的效能要高;
並且Serializable在序列化的時候會產生大量的臨時變數,從而會引起頻繁的GC,因此在Android開發中,會推薦使用Parcelable進行序列化。


在序列化時,碰到Parcelabe類中,巢狀Parcelabe類,會稍微有點不一樣。

如下:

public class FacialPart implements Parcelable {

    private int id;
    private float scale = 1.0f;
    private float tx;
    private float ty;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public float getScale() {
        return scale;
    }

    public void setScale(float scale) {
        
        this.scale = scale;
    }

    public float getTx() {
        return tx;
    }

    public void setTx(float tx) {
        this.tx = tx;
    }

    public float getTy() {
        return ty;
    }

    public void setTy(float ty) {
        this.ty = ty;
    }

    public FacialPart() {
        this(0);
    }
    
    public FacialPart(int id) {
        this.id = id;
    }
    

    @Override
    public String toString() {

        return "FacialPart[id=" + id + ", scale=" + scale + ", tx=" + tx + ", ty=" + ty + "]";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flag) {
        
        dest.writeInt(id);
        dest.writeFloat(scale);
        dest.writeFloat(tx);
        dest.writeFloat(ty);
    }
    
    public static final Parcelable.Creator<FacialPart> CREATOR = new Parcelable.Creator<FacialPart>() {

        @Override
        public FacialPart createFromParcel(Parcel in) {

            int id = in.readInt();
            float s = in.readFloat();
            float tx = in.readFloat();
            float ty = in.readFloat();
            
            FacialPart part = new FacialPart(id);
            part.setScale(s);
            part.setTx(tx);
            part.setTy(ty);
            
            return part;
        }

        @Override
        public FacialPart[] newArray(int size) {
            
            return new FacialPart[size];
        }
    };
}

public class DetectedFace  implements Parcelable {

    private FacialPart facePart;
    private FacialPart nosePart;
    private FacialPart eyePart;
    private FacialPart eyebrowPart;
    private FacialPart mouthPart;
    
    private List<FacialPart> parts;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flag) {

        dest.writeParcelable(facePart, flag);
        dest.writeParcelable(nosePart, flag);
        dest.writeParcelable(eyePart, flag);
        dest.writeParcelable(eyebrowPart, flag);
        dest.writeParcelable(mouthPart, flag);

	dest.writeTypedList(parts);  
    }
    
    public static final Parcelable.Creator<DetectedFace> CREATOR = new Parcelable.Creator<DetectedFace>() {

        @Override
        public DetectedFace createFromParcel(Parcel in) {
            
            
            
            FacialPart facePart = in.readParcelable(FacialPart.class.getClassLoader());
            FacialPart nosePart = in.readParcelable(FacialPart.class.getClassLoader());
            FacialPart eyePart = in.readParcelable(FacialPart.class.getClassLoader());
            FacialPart eyebrowPart = in.readParcelable(FacialPart.class.getClassLoader());
            FacialPart mouthPart= in.readParcelable(FacialPart.class.getClassLoader());
            
	    List<FacialPart> parts = new ArrayList<FacialPart>();  
	    in.readTypedList(parts, FacialPart.CREATOR);  

            DetectedFace face = new DetectedFace();

            face.facePart = facePart;
            face.nosePart = nosePart;
            face.eyePart = eyePart;
            face.eyebrowPart = eyebrowPart;
            face.mouthPart = mouthPart;
	    
	    face.parts = parts;
            
            return face;
        }

        @Override
        public DetectedFace[] newArray(int size) {
            return new DetectedFace[size];
        }  
        
    };
}

關鍵的程式碼就是讀取時,使用**.class.getClassLoader()進行讀取;
如:
FacialPart facePart = in.readParcelable(FacialPart.class.getClassLoader());

而對於巢狀的列表,則使用如下程式碼:
List<FacialPart> parts = new ArrayList<FacialPart>();  
in.readTypedList(parts, FacialPart.CREATOR);