Android中的两种序列化:Parcelable和Serialable

Quibbler 2020-12-13 702

Android中的两种序列化:Parcelable和Serialable


        Android开发中常常用到序列化,典型的应用就是Intent携带数据(不宜携带过多数据)。跨进程传输是将对象序列化,转换成可存储或可传输的状态,再通过网络等方式传输。

    public class Intent implements Parcelable, Cloneable {
	    ...
    }

        Intent之所以能够跨进程传输因为它实现了Android特有的序列化接口Serialable。这也是开发中用到序列化的原因之一:

        ①永久性保存对象,保存对象的字节序列到本地文件

        ②通过序列化对象在网络中传递对象 

        ③通过序列化对象在进程间传递对象



1、Serialable*

        Serialable是Java自带的序列化接口:表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。

    public interface Serializable {
    }

        需要序列化的类,实现Serialable接口声明一下该类需要序列化即可:

    public class Info implements Serializable {
        private static final long serialVersionUID = 974450303339087901L;
        
	private String name;
    }

        注意需要提供一个serialVersionUID常量,标识独一无二的一个类。参考生成Serializable接口serialVersionUID



2、Parcelable

        Parcelable序列化是Android独有的序列化方式。

        为什么不直接采用Java自带的Serialable序列化呢?Serializable效率过慢,而Parcelable比Serializable性能高。Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。对于Android应用程序运行在移动设备上,对性能有一定的要求。


2.1、Parcelable接口

        两个抽象方法,序列化必须要实现:

        public int describeContents():内容描述接口,不用管。返回0即可。

        public void writeToParcel(Parcel dest, int flags):数据写入序列流接口。

       两个接口:必须创建实现Creator<T>接口的静态实例,并且名称为CREATOR

        Creator<T>,必须作为公共CREATOR字段实现并提供的接口,该字段从Parcel生成Parcelable类的实例T

    public interface Creator<T> {
        /**
         * 创建Parcelable类的新实例,然后从给定的Parcel实例化该实例。该数据先前由Parcelable#writeToParcel写入
         */
        public T createFromParcel(Parcel source);
        
        /**
         * 创建一个新的Parcelable类数组
         */
        public T[] newArray(int size);
    }

        ClassLoaderCreator<T>继承自Creator<T>,基本用不到

    public interface ClassLoaderCreator<T> extends Creator<T> {
        /**
         * Create a new instance of the Parcelable class
         */
        public T createFromParcel(Parcel source, ClassLoader loader);
    }


2.2、标准示例

        通过Parcelable序列化的典型实现代码如下:

  public class MyParcelable implements Parcelable {
        private int mData;
   
        public int describeContents() {
            return 0;
        }
   
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(mData);
        }
   
        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();
        }
    }

        三个要点:实现两个接口方法;创建一个实现Creator<T>接口的静态实例,并且名称为CREATOR;数据序列化顺序和反序列化顺序要一致。

        如果需要序列化的类属性过多,一个一个写起来挺麻烦。推荐一个Parcelable序列化插件款速实现Parcelable序列化。


2.3、序列化流程

        略。这块源码可以从Intent携带数据时的putExtra(String name, Parcelable value)方法,再到获取时的getParcelableExtra(String name)方法看起。了解完整的序列化和反序列化流程。

        与序列化相关的Native层源码在../frameworks/native/libs/binder/Parcel.cpp中。



3、总结

        Serializable是Java自带的序列化方式,Parcelable是Android特有的序列化方式。

        Serializable序列化会产生大量的临时变量,引起频繁的GC,造成内存抖动,不适合Android应用程序。

        Parcelable比Serializable性能高、效率高,Android开发中使用Parcelable。

        Serializable可以将对象通过网络传输 或 磁盘存储。Parcelable无法将对象保存在存储中。



参考资料:

        Android Developers > Reference > Parcelable

        Android Developers > Reference > Parcelable.Creator

        Android之Parcelable解析

        程序员必懂小技巧之Parcelable

        

不忘初心的阿甘
最新回复 (0)
    • 安卓笔记本
      2
        登录 注册 QQ
返回
仅供学习交流,切勿用于商业用途。如有错误欢迎指出:fluent0418@gmail.com