Android Parcelable 接口用法小结

2019-01-26  本文已影响0人  无敌未央様

简单的来说就是:在Intent或Bundle中无法直接放对象,必须把对象序列化为二进制流才行,传输完成后要进行反序列化,重新从流变为对象。

进行Android开发的时候,无法将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。简单来说就是将对象转换为可以传输的二进制流(二进制序列)的过程,这样我们就可以通过序列化,转化为可以在网络传输或者保存到本地的流(序列),从而进行传输数据 ,那反序列化就是从二进制流(序列)转化为对象的过程.
Parcelable是Android为我们提供的序列化的接口,Parcelable相对于Serializable的使用相对复杂一些,但Parcelable的效率相对Serializable也高很多,这一直是Google工程师引以为傲的,有时间的可以看一下Parcelable和Serializable的效率对比 Parcelable vs Serializable 号称快10倍的效率

用的时候要注意:
写构造方法的时候要写参数为Parcel的情况
要实现序列化、反序列化、描述这三个功能
描述很简单,没有特殊情况就返回0,目的是添加注释描述类
序列化要注意使用对于参数类型的write

用一个小例子说明一下:

public class People implements Parcelable {
    private String mName;
    private int mAge;
    private boolean  mGender;
    private ArrayList<String> mJobs;
    private Friend mFriend;
    private ArrayList<Friend> mFriends= new ArrayList<>()

    public People() {}

    /**
     * 描述
     * 返回的是内容的描述信息
     * 只针对一些特殊的需要描述信息的对象,需要返回1,其他情况返回0就可以
     *
     * @return
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 序列化
     *
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
        dest.writeInt(mAge);
        dest.writeByte((byte) (mGender ? 1 : 0));
        dest.writeStringList(mJobs);

        dest.writeParcelable(mFriend, flags);// 序列化对象的时候传入要序列化的对象和一个flag,这里的flag几乎都是0,除非标识当前对象需要作为返回值返回,不能立即释放资源

        dest.writeTypedList(mFriends);

    }

    /**
     * 负责反序列化
     */
    public People(Parcel source) {
        mName= source.readString();
        mAge= source.readInt();
        mGender= source.readByte() != 0;
        mJobs= in.createStringArrayList();

        mFriend= source.readParcelable(Friend.class.getClassLoader()); // 读取对象需要提供一个类加载器去读取,因为写入的时候写入了类的相关信息

        mFriends.readTypedList(mFriends, Friend.CREATOR); //对应writeTypeList



    }

    private static final Creator<People> CREATOR = new Creator<People>() {
        /**
         * 从序列化对象中,获取原始的对象
         * @param source
         * @return
         */
        @Override
        public Album createFromParcel(Parcel source) {
            return new People(source);
        }

        /**
         * 创建指定长度的原始对象数组
         * @param size
         * @return
         */
        @Override
        public People[] newArray(int size) {
            return new People[size];
        }
    };
}

下图是过程模型:


Parcelable过程模型

写入和读取集合有两种方式,
一是写入类的相关信息,然后通过类加载器去读取, –> writeList | readList;
二是不用类相关信息,创建时传入相关类的CREATOR来创建 –> writeTypeList | readTypeList | createTypedArrayList
第二种效率高一些

一定要注意如果有集合定义的时候一定要初始化
public ArrayList<T> demo = new ArrayList<>();

上一篇下一篇

猜你喜欢

热点阅读