美文网首页
Android学习--Bundle(二)Parcelable

Android学习--Bundle(二)Parcelable

作者: 陈可积 | 来源:发表于2021-02-26 17:27 被阅读0次

    参考资料:https://www.jianshu.com/p/32a2ec8f35ae
    https://www.cnblogs.com/tangZH/p/10998065.html

    1.Parcelable的简单介绍

    介绍Parcelable不得不先提一下Serializable接口,Serializable是Java为我们提供的一个标准化的序列化接口,那什么是序列化呢? ---- 简单来说就是将对象转换为可以传输的二进制流(二进制序列)的过程,这样我们就可以通过序列化,转化为可以在网络传输或者保存到本地的流(序列),从而进行传输数据 ,那反序列化就是从二进制流(序列)转化为对象的过程.

    那我们看一下Android源码中的Parcelable

        /**
         * Interface for classes whose instances can be written to
       * and restored from a {@link Parcel}.  Classes implementing the Parcelable
     * interface must also have a non-null static field called <code>CREATOR</code>
     * of a type that implements the {@link Parcelable.Creator} interface.
     * 
     * <p>A typical implementation of Parcelable is:</p>
     * 
     * <pre>
     * 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();
     *     }
     * }</pre>
     */
    

    通过源码中的介绍 可以知道,Parcelable接口的实现类是可以通过Parcel写入和恢复数据的,并且必须要有一个非空的静态变量 CREATOR, 而且还给了一个例子,这样我们写起来就比较简单了,但是简单的使用并不是我们的最终目的

    通过查看Android源码中Parcelable可以看出,Parcelable实现过程主要分为序列化,反序列化,描述三个过程,下面分别介绍下这三个过程

    2 Parcel的简介

    在介绍之前我们需要先了解Parcel是什么?Parcel翻译过来是打包的意思,其实就是包装了我们需要传输的数据,然后在Binder中传输,也就是用于跨进程传输数据

    简单来说,Parcel提供了一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象,下图是这个过程的模型。

    image

    Parcel可以包含原始数据类型(用各种对应的方法写入,比如writeInt(),writeFloat()等),可以包含Parcelable对象,它还包含了一个活动的IBinder对象的引用,这个引用导致另一端接收到一个指向这个IBinder的代理IBinder。

    <meta charset="utf-8">

    3 Parcelable中的三大过程介绍(序列化,反序列化,描述)

    到这里,基本上关系都理清了,也明白简单的介绍和原理了,接下来在实现Parcelable之前,介绍下实现Parcelable的三大流程
    首先写一个类实现Parcelable接口,会让我们实现两个方法

    image

    1.3.1 描述

    其中describeContents就是负责文件描述,首先看一下源码的解读

    image

    通过上面的描述可以看出,只针对一些特殊的需要描述信息的对象,需要返回1,其他情况返回0就可以

    1.3.2 序列化

    我们通过writeToParcel方法实现序列化,writeToParcel返回了Parcel,所以我们可以直接调用Parcel中的write方法,基本的write方法都有,对象和集合比较特殊下面单独讲,基本的数据类型除了boolean其他都有,Boolean可以使用int或byte存储

    举个例子:我们将上面的User对象实现序列化,User对象包含三个字段 age,name,isMale

     /**
     * 该方法负责序列化
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(age);
        dest.writeString(name);
        // boolean 可以使用int或byte方式进行存储,怎么存就怎么取
        dest.writeInt(isMale ? 1 : 0);
    }
    
    

    1.3.3 反序列化

    反序列化需要定义一个CREATOR的变量,上面也说了具体的做法,这里可以直接复制Android给的例子中的,也可以自己定义一个(名字千万不能改),通过匿名内部类实现Parcelable中的Creator的接口

    /**
     * 负责反序列化
     */
    public static final Creator<User> CREATOR = new Creator<User>() {
        /**
         * 从序列化后的对象中创建原始对象
         */
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }
    
        /**
         * 创建指定长度的原始对象数组
         */
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
    
    public User(Parcel parcel) {
        age = parcel.readInt();
        name = parcel.readString();
        isMale = parcel.readInt() == 1;
    }
    

    作者:MrQ_Android
    链接:https://www.jianshu.com/p/32a2ec8f35ae
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:Android学习--Bundle(二)Parcelable

          本文链接:https://www.haomeiwen.com/subject/wjcvfltx.html