zoukankan      html  css  js  c++  java
  • Serializable 和Parcelable 的区别

    1、作用

    Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、RMI(Remote Method Invocation)以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。使用了反射技术,并且期间产生临时对象

    Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

    2、效率及选择

    Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

    3、高级功能上

    Serializable序列化不保存静态变量,可以使用transient关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义

    如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。换句话说,用transient关键字标记的成员变量不参与序列化过程

    4、编程实现

    对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。

    而Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量(AS有相关插件 一键生成所需方法),实际上就是将如何打包和解包的工作自己来定义,而序列化的这些操作完全由底层实现。

    Parcelable的一个实现例子如下

    public class MyParcelable implements Parcelable {
         private int mData;
         private String mStr;
     
         public int describeContents() {
             return 0;
         }
     
         // 写数据进行保存
         public void writeToParcel(Parcel out, int flags) {
             out.writeInt(mData);
             out.writeString(mStr);
         }
     
         // 用来创建自定义的Parcelable的对象
         public static final Parcelable.Creator<MyParcelable> CREATOR
                 = new Parcelable.Creator<MyParcelable>() {
             public MyParcelable createFromParcel(Parcel in) {
                 return new MyParcelable(in);
             }
     
             public MyParcelable[] newArray(int size) {
                 return new MyParcelable[size];
             }
         };
         
         // 读数据进行恢复
         private MyParcelable(Parcel in) {
             mData = in.readInt();
             mStr = in.readString();
         }
     }

    从上面我们可以看出Parcel的写入和读出顺序是一致的。如果元素是list读出时需要先new一个ArrayList传入,否则会报空指针异常。如下:

    list = new ArrayList<String>();
    in.readStringList(list);

    PS: 在自己使用时,read数据时误将前面int数据当作long读出,结果后面的顺序错乱,报如下异常,当类字段较多时务必保持写入和读取的类型及顺序一致。

    11-21 20:14:10.317: E/AndroidRuntime(21114): Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4126ed60: Unmarshalling unknown type code 3014773 at offset 164
  • 相关阅读:
    保持URL不变和数字验证
    centOS ftp key?
    本地环境测试二级域名
    linux 解决You don't have permission to access 问题
    php smarty section loop
    php header Cannot modify header information headers already sent by ... 解决办法
    linux部分命令
    Linux 里面的文件操作权限说明
    用IT网络和安全专业人士视角来裁剪云的定义
    SQL Server 2008 R2炫酷报表"智"作有方
  • 原文地址:https://www.cnblogs.com/genggeng/p/10073021.html
Copyright © 2011-2022 走看看