关于parcel的介绍

在查看Bundle源码时,Bundle继承自BaseBundle,实现了Cloneable,Parcelable两个接口。

Cloneable是个空接口,只是某个类重写了Object的clone()方法时,需要实现Cloneable接口,否则在调用clone()方法时,会报CloneNotSupportedExcption异常,因此Cloneable只是合法调用的clone()的标识。关于Cloneable的使用建议,请参考 http://www.artima.com/intv/bloch13.html

要分析Parceable,先要了解Parcel,请参考 

1.https://developer.android.com/reference/android/os/Parcel.html

2.http://stackoverflow.com/questions/1626667/how-to-use-parcel-in-android

3.http://prasanta-paul.blogspot.jp/2010/06/android-parcelable-example.html

在Android developer上,是这样描述Parcel的

Container for a message (data and object references) that can be sent through an IBinder. A Parcel can contain both flattened data that will be unflattened on the other side of the IPC (using the various methods here for writing specific types, or the general Parcelable interface), and references to live IBinder objects that will result in the other side receiving a proxy IBinder connected with the original IBinder in the Parcel.
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.
The bulk of the Parcel API revolves around reading and writing data of various types. There are six major classes of such functions available.

Parcel是个消息(data and object references)的容器,可以通过IBinder发送,IBinder是android用于进程间通信的方式(IPC)。Parcel可以携带序列化后(flattened/marshalled/serialized,通过使用多种类型的writing函数或者Parcelable接口)的数据,在IPC的另外一侧反序列化数据(变回序列化前的对象);Parcel也可以携带活动的IBinder对象,传递到Parcel中与原本IBinder相连的代理IBinder中。

Parcel不是通用序列化机制(Android特有,java的序列化机制是Serilizable,在效率上不如Parcel)。这个class(以及相应的Parcelable API,用于将用于将任意对象转换成Parcel)被设计为高性能的IPC传输方式。因此将Parcel数据放置在持久化存储位置是不合适的,任何基于Parcel中数据实现的变化都会导致旧数据不可读。

与Parcel 相关的API有多种读写不同类型的方式,主要的6种类如:

Primitives
Primitive Arrays
Parcelables
Bundles
Active Objects
Untyped Containers

示例代码片段:

假如有个对象如下,通过Intent在activity间传递

public class ParcelData{
    int id;
    String name;
    public ParcelData(int mId,String mName){
        id = mId;
        name = mName;
    }
}

如果将ParcelData放在Intent中,程序会报错,因为ParcelData没有序列化,所以要实现序列化的接口,在这里我们使用Parcelable

public class ParcelData implements Parcelable{
    int id;
    String name;
    public ParcelData(int mId,String mName){
        id = mId;
        name = mName;
    }
}

要实现Parcelable接口,程序提示覆盖两个函数,用于序列化对象

describeContents() ----描述将要进行序列化的对象的类型

writeToParcel(Parcel dest, int flags) -----真正进行序列化的位置,需要单独的序列化对象的的每个元素

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(id);
    dest.writeString(name);

}

describeContents()和writeToParcel(Parcel dest, int flags)是为了将对象序列化,若是得到序列化后的流,怎么反序列化成对象,需要在ParcelData中定义一个CREATOR的变量

protected ParcelData(Parcel in) {
    id = in.readInt();
    name = in.readString();
}
public static final Creator<ParcelData> CREATOR = new Creator<ParcelData>() {
    @Override
    public ParcelData createFromParcel(Parcel in) {
        return new ParcelData(in);
    }

    @Override
    public ParcelData[] newArray(int size) {
        return new ParcelData[size];     返回ParcelData类型的数组
    }
};
到此ParcelData已经实现,可以通过Intent在不同进程间传递。

在第一个Activity中创建序列化对象(MainActivity.java)

ArrayList<ParcelData> dataList = new ArrayList<ParcelData>();
Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);

ParcelData pd1 = new ParcelData(13,"beijing");
ParcelData pd2 = new ParcelData(25,"guangzhou");
dataList.add(pd1);
dataList.add(pd2);

intent.putParcelableArrayListExtra("test",dataList);   将ParcelData类型的链表放置在Intent中
startActivity(intent);
在第二个Activity中反序列化(SecondActivity)
ArrayList<ParcelData> dataList = new ArrayList<ParcelData>();
dataList = getIntent().getParcelableArrayListExtra("test");    从Intent中取出ParcelData类型的对象链表



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值