项目里需要用到intent传递对象,所以用到了Parcelable
主要内容摘自
http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
先看实际应用
1.
public class Lesson implements Parcelable {
private String title;
private String id;
private boolean progress;
private String type;
private boolean learned;
private boolean downloaded;
public Lesson(String title, String id, boolean progress, String type){
this.title = title;
this.id = id;
this.progress = progress;
this.type = type;
this.learned = false;
this.downloaded = false;
}
public boolean isDownloaded() {
return downloaded;
}
public void setDownloaded(boolean downloaded) {
this.downloaded = downloaded;
}
public String getTitle() {
return title;
}
public String getId() {
return id;
}
public boolean isProgress() {
return progress;
}
public String getType() {
return type;
}
public void setLearned(boolean learned) {
this.learned = learned;
}
public boolean isLearned() {
return learned;
}
@Override
public int describeContents() {
return 0;
}
// write Lesson
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(title);
out.writeString(id);
out.writeByte((byte) (progress ? 1 : 0));
out.writeString(type);
out.writeByte((byte) (learned ? 1 : 0));
}
private Lesson(Parcel in) {
title = in.readString();
id = in.readString();
progress = in.readByte() != 0;
type = in.readString();
learned = in.readByte() != 0;
}
//read Pesson
public static final Parcelable.Creator<Lesson> CREATOR
= new Parcelable.Creator<Lesson>() {
public Lesson createFromParcel(Parcel in) {
return new Lesson(in);
}
public Lesson[] newArray(int size) {
return new Lesson[size];
}
};
}
然后在需要传递的地方
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("lesson", lesson);
startActivity(intent);
Lesson lesson = getIntent().getParcelableExtra("lesson");
为了方便理解:
贴上Parcelable的定义
public interface Parcelable
{
//内容描述接口,基本不用管
public int describeContents();
//写入接口函数,打包
public void writeToParcel(Parcel dest, int flags);
//读取接口,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数传入
//为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例
public interface Creator<T>
{
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
}
2、实现Parcelable步骤
1)implements Parcelable
2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据
3)重写describeContents方法,内容接口描述,默认返回0就可以
4)实例化静态内部对象CREATOR实现接口Parcelable.Creator
public static final Parcelable.Creator CREATOR
注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。
简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。
还有一种效率低一些的用Serializable 实现的
public class Person implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Lesson lesson = getIntent().getSerializable("lesson");
用Parcelable的方法更好,原因如下:
为什么要将对象序列化?
1、永久性保存对象,保存对象的字节序列到本地文件中;
2、用过序列化对象在网络中传递对象;
3、通过序列化对象在进程间传递对象。
1、实现Serializable接口
Serializable的作用是将数据对象存入字节流当中,在需要时重新生成对象,主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。
implements Serializable接口的的作用就是给对象打了一个标记,系统会自动将其序列化。
2、实现Parcelable接口
1)为什么要实现Parfcelable接口来实现在Intent中传递对象?
a、在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable类。
b、Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
注意:Parcelable不能使用在将数据存储在磁盘上的情况,因为Parcelable不能很好的保存数据的持续性在外界有变化的情况下。因此在这种情况下,建议使用Serializable
2) Android中的新的序列化机制
在Android系统中,针对内存受限的移动设备,因此对性能要求更高,Android系统采用了新的IPC(进程间通信)机制,要求使用性能更出色的对象传输方式。因此Parcel类被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。
Parcel的序列化和反序列化的读写全是在内存中进行,所以效率比JAVA序列化中使用外部存储器会高很多。
Parcel类
就应用程序而言,在常使用Parcel类的场景就是在Activity间传递数据。在Activity间使用Intent传递数据的时候,可以通过Parcelable机制传递复杂的对象。
Parcel机制:本质上把它当成一个Serialize就可以了。只是Parcel的对象实在内存中完成的序列化和反序列化,利用的是连续的内存空间,因此更加高效。