話說android Activity之間數據傳遞

        本人原創作品,謝絕轉載!    

        Activity之間傳數據時,爲了避免麻煩,往往會將一些值封裝成對象,然後將整個對象傳遞過去。傳對象的時候有兩種情況,一種是實現Parcelable接口,一種是實現Serializable接口。下面說說這些情況。

    一、傳遞Parcelable對象:

        代碼:Programmer.java

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

public class Programmer implements Parcelable {

	public String sex;
	public String name;
	
	public Programmer() {}
	
	public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeString(sex);
        out.writeString(name);
    }

    public static final Parcelable.Creator<Programmer> CREATOR
            = new Parcelable.Creator<Programmer>() {
        public Programmer createFromParcel(Parcel in) {
            return new Programmer(in);
        }

        public Programmer[] newArray(int size) {
            return new Programmer[size];
        }
    };
    
    private Programmer(Parcel in) {
    	sex = in.readString();
        name = in.readString();
    }
	
}

代碼:Worker.java

import java.util.ArrayList;

import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;

public class Worker implements Parcelable {

	public String name;
	public int age;
	public Programmer programmer;
	public ArrayList<Programmer> pros = new ArrayList<Programmer>();
	public Bitmap icon;
	public Designer designer;
	
	public Worker() {}
	
	public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeString(name);
        out.writeInt(age);
        out.writeParcelable(programmer, flags);
        out.writeList(pros);
        out.writeParcelable(icon, flags);
        out.writeSerializable(designer);
    }

    public static final Parcelable.Creator<Worker> CREATOR
            = new Parcelable.Creator<Worker>() {
        public Worker createFromParcel(Parcel in) {
            return new Worker(in);
        }

        public Worker[] newArray(int size) {
            return new Worker[size];
        }
    };
    
    private Worker(Parcel in) {
        name = in.readString();
        age = in.readInt();
        programmer = in.readParcelable(Programmer.class.getClassLoader()); // 這個地方的ClassLoader不能爲null
        pros = in.readArrayList(Programmer.class.getClassLoader()); // 這個地方的ClassLoader不能爲null
        icon = in.readParcelable(null); // 這個地方可以爲null
        designer = (Designer) in.readSerializable();
    }
}
        代碼:Designer.java
import java.io.Serializable;

public class Designer implements Serializable {

	public String name;
	public int age;
}

注意Parcel out和in對應的屬性順序不能錯,否則得不到值;如果想傳遞的值沒有write和read,同樣也是獲取不到值的。

實現Parcelable接口我採用的做法是,從android API文檔中找到Parcelable接口,詳見http://developer.android.com/reference/android/os/Parcelable.html,將demo copy,然後將MyParcelable類名全部替換,再填寫write和read的值。在填寫值的時候上面的代碼給出了一些示例,有時候會出現以下錯誤:

      1.Caused By:android.os.BadParcelableException: ClassNotFoundException when unmarshalling,原因是ClassLoader設置不對,或者沒有傳入ClassLoader

       2.java.lang.RuntimeException: Parcelable encountered IOException writing serializable object,原因是傳遞的Parcelable對象裏面的對象也要Parcelable或者Serializable


二、傳遞Serializable對象:

        Activity之間傳遞Serializable對象時,被傳遞的Serializable對象裏面的自定義成員對象(非API中的Serializable對象)也要實現Serializable接口,否則會出現Caused by: java.io.NotSerializableException異常。從上面的代碼可以看出,在Parcelable對象中是可以傳遞Serializable對象的,但Serializable對象裏面傳遞的時候可不可以有Parcelable?回答是否定的,一樣會產生java.io.NotSerializableException異常。


三、傳遞集合:

        android api中只能傳遞Parcelable對象的集合,而不能傳遞Serializable對象的集合,也就是隻能傳遞ArrayList<Bitmap>,卻不能傳遞ArrayList<Designer>。剛剛開始學android的時候,對象都是被封裝成Serializable,再傳遞,因爲Serializable是JAVASE裏面的本地化接口,很熟悉,當時也產生疑問,爲什麼會有Parcelable接口,這兩個有什麼區別?到後來,當Serializable不能滿足要求的時候就明白了,android利用Pacelable對自己的東西進行封裝,就像Worker中的Bitmap,在read的時候可以不需要設置ClassLoader。


如有遺漏不當之處,歡迎批評指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章