话说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 CREATOR
            = new Parcelable.Creator() {
        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 pros = new ArrayList();
	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 CREATOR
            = new Parcelable.Creator() {
        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,却不能传递ArrayList。刚刚开始学android的时候,对象都是被封装成Serializable,再传递,因为Serializable是JAVASE里面的本地化接口,很熟悉,当时也产生疑问,为什么会有Parcelable接口,这两个有什么区别?到后来,当Serializable不能满足要求的时候就明白了,android利用Pacelable对自己的东西进行封装,就像Worker中的Bitmap,在read的时候可以不需要设置ClassLoader。


如有遗漏不当之处,欢迎批评指正!

你可能感兴趣的:(android技巧总结)