Serializable和Parcelable序列化

前言

  • Android中实现序列化两个选择:

        一是实现Serializable接口(是JavaSE本身就支持的,接口中没有任何方法,可以理解为一个标记),二是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC)),推荐用这种方法提高性能。

  • 实现Parcelable作用:

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

  • 序列化特点是:

a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
c) static,transient后的变量不能被序列化;
d) 序列化时,只对对象的状态进行保存,而不管对象的方法;

e对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构.

f并非所有的对象都可以序列化,原因:1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且也是没有必要这样实现。

  • 两种序列化比较:

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。

Parcelable举例:

public class XuLieHua implements Parcelable {
    String a = "序列化数据 a ";
    String b= "序列化数据 b ";
    String c= "序列化数据 c ";

	public XuLieHua() {}//若用空参构造,可以通过set()方法给a赋值
    public XuLieHua(Parcel in) {
   //如果元素数据是list类型的时候需要: lits = new ArrayList<?> in.readList(list); 
  //读出和写入的数据类型必须相同.若不想对部分关键字序列化,可使用transient关键字或static修饰
        a = in.readString();    //反序列化获得对象中对应的的数据,在json解析时会用到
        b = in.readString();
        c = in.readString();
    }

   public void setA(String a) {
        this.a = a;
    }

	//Parcelabel的实现,还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator接口
    public static final Creator<XuLieHua> CREATOR = new Creator<XuLieHua>() { 
        @Override
        public XuLieHua createFromParcel(Parcel in) {
            return new XuLieHua(in); //从Parcel容器中取出数据并进行转换.
        }

        @Override
        public XuLieHua[] newArray(int size) {
            return new XuLieHua[size];
        }
    };

    @Override
    public int describeContents() { //内容接口描述,设置为0即可
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) { 
		//将我们的对象存入Parcel中,写入数据的顺序和读出数据的顺序必须是相同的.
		//该方法将对象数据序列化成一个Parcel对象(序列化之后成为Parcel对象.以便Parcel容器取出数据)
        parcel.writeString(a);
        parcel.writeString(b);
        parcel.writeString(c);
    }

对象在activity间传递:

activity间对象的传递 传出方:
	  Intent intent = new Intent(this,ThreeActivity.class);
        Bundle b = new Bundle();
        XuLieHua xuLie1 = new XuLieHua();
        xuLie1.a = "I am xuelie a";
        xuLie1.b = "I am xuelie b";
        xuLie1.c = "I am xuelie c";
        b.putParcelable("aa",xuLie1);
        intent.putExtra("bundle", b);
//        intent.putExtra("aa", xuLie1); //或用这种方式
        startActivity(intent);

activity间对象的传递 接收方:
	 XuLieHua bb = getIntent().getParcelableExtra("aa");//用intent省去bundle转换过程
        if (bb!=null) {
            Log.d("bb序列化后得到其中数据"+ bb.b, String.valueOf(bb.a.equals(bb.b)));
        }

        Bundle bundle = getIntent().getBundleExtra("bundle");
        XuLieHua cc = bundle.getParcelable("aa");
        Log.d("cc序列化后得到其中数据"+ cc.b, String.valueOf(cc.a.equals(cc.b)));
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值