android 传递自定义对象数据详解

来源:互联网 发布:linux进程 编辑:程序博客网 时间:2024/05/22 14:51

今天和同学交流传递集合数据时候,我直接建议同学使用putSerializable传递一个序列化对象,然后获取到该对象中list集合拿来使用,但是同学说她们不这样用使用putParcelableArrayListExtra直接传递一个集合,我就有点好奇这两者有什么不同,我当初为什么使用第一种方法,就去网上查了资料,大彻大悟。

自定义对象的传递:
通过intent 传递自定义对象的方法有两个,第一是实现Serialization接口,第二是实现Parcelable接口。
首选推荐Parceable,android中的很多数据类型都是实现Serialable接口方式来传递的,例如 Intent、Bundle、Bitmap、Uri等等。
android Parcelable化的提供了一个接口 Parcelable和一个工具类 Parcel
Parcelable:一个规范接口,定义实现Parcelable需要实现的功能
Parcel:数据存取的工具类,供用户在实现Parcelable接口时存取自定义数据用,也供系统传递数据时使用。

Parcelable实现要点:需要实现三个东西
1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.声明如下:
writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc
2)describeContents方法。没搞懂有什么用,反正直接返回0也可以
3)静态的Parcelable.Creator接口,本接口有两个方法:
createFromParcel(Parcel in) 实现从in中创建出类的实例的功能
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
看到上面解释后我明白了两者都可以传递自定义对象,那它们有什么不同之处呢?

一 序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。 


二 至于选取哪种可参考下面的原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。

看到上面解释后,我才知道自己犯了多大错误。惊讶惊讶同样也抱着对Parcelable的好感和好奇心去做了一个Demo进行测试。在测试过程中也碰到了一些问题总结如下:

1、仅仅传递一个自定义对象,自定义对象中都是基本数据类型(集合类型也是基本数据类型),直接实现Parcelable接口,按照提示实现其中方法,通过putExtra传递即可。

2、传递的自定义对象中含有集合(此处的自定义对象实现了Parcelable接口),集合中的数据也是自定义对象类型(集合必须是ArrayList,否则会报错),此时需要注意以下两点:

    (1)对于没有经验的我,集合中的自定义对象就直接定义一个bean(没有实现Parcelable接口和Serialization接口),传递数据时候直接报错:Parcel: unable to marshal value 

    (2)针对上面的问题,百度才知道集合中的数据类型要实现Serialization接口或者Parcelable接口,实现Parcelable接口时候,注意集合要用ArrayList定义,最开始我在protected构造方法中使用的是ClassLoader.getSystemClassLoader(),运行报错:android.os.BadParcelableException: ClassNotFoundException when unmarshal 修改为Books.class.getClassLoader()即可

第一次使用Parcelable传递自定义对象真是呕心沥血大哭大哭,现附上代码,以供参考。

3、直接传递集合,集合中的bean实现Parcelable接口,使用putParcelableArrayListExtra传递数据,注意:要使用ArrayList定义集合。

Students.java:

public class Students implements Parcelable {    public ArrayList<Books> list;    public Students(ArrayList<Books> list){        this.list = list;    }    protected Students(Parcel in) {        list = in.readArrayList(Books.class.getClassLoader());    }    public static final Creator<Students> CREATOR = new Creator<Students>() {        @Override        public Students createFromParcel(Parcel in) {            return new Students(in);        }        @Override        public Students[] newArray(int size) {            return new Students[size];        }    };    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel parcel, int i) {        parcel.writeList(list);    }}
Books.java:

public class Books implements Parcelable{    public String name;    public int price;    public  Books(String name,int price){        this.name = name;        this.price = price;    }    protected Books(Parcel in) {        name = in.readString();        price = in.readInt();    }    public static final Creator<Books> CREATOR = new Creator<Books>() {        @Override        public Books createFromParcel(Parcel in) {            return new Books(in);        }        @Override        public Books[] newArray(int size) {            return new Books[size];        }    };    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel parcel, int i) {        parcel.writeString(name);        parcel.writeInt(price);    }}




0 0
原创粉丝点击