• Android 序列化Parcelable的使用详解


    背景:

    在Java虚拟机中,对象的传递称为数据传递不可或缺的一部分,但如果一旦虚拟机停止工作,该对象在内存中也就被释放,地址空间不存在,对象自然就不能再被重复利用,如果我们想持久使用这个对象怎么办?写到文件中?存数据库?最好的方法就是能够保存下来,把一个对象的空间地址以及属性保存下来,在Java中已提供了一个接口Serializable。

    1.Serializable是Java的JDK提供的,由于该序列化不够丝滑,在PC等大型操作系统中使用,体验不出来,如果在Adnroid 虚拟机中,数据的传递存在一定的差异,这时,google官方提供了新的序列化对象Parcelable

    Parcelable相比较Serializable要复杂的很多,Serializable序列化只要对象继承该接口,即可。但是Parcelable需要我们手动去分装

    Parcelable序列化的封装

    说明:

    如果最外层Bean需要实现Parcelable,那么内部的变量也是一个类对象,也要实现序列化,可以先从变量类开始序列化,最后实现外层bean的序列化

    序列化之前先把变量定义好,这样用助于后面序列化的操作

    1.IDE自动封装

    1.1先将当前类继承接口Parcelable

    1.2将鼠标悬停在错误提示位置,这个时候IDE提示如下

    1.3 我们只需要点击Add  implementation Parcelable

    1.4IDE会自动完成组装,自动读写变量

    结果如下:

    public class MyParcelBean implements Parcelable {
    
    
        private int age;
        private String name;
        private boolean sex;
    
    
        protected MyParcelBean(Parcel in) {
            age = in.readInt();
            name = in.readString();
            sex = in.readByte() != 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(age);
            dest.writeString(name);
            dest.writeByte((byte) (sex ? 1 : 0));
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        public static final Creator<MyParcelBean> CREATOR = new Creator<MyParcelBean>() {
            @Override
            public MyParcelBean createFromParcel(Parcel in) {
                return new MyParcelBean(in);
            }
    
            @Override
            public MyParcelBean[] newArray(int size) {
                return new MyParcelBean[size];
            }
        };
    }

    **************************************************************************************************

    2.手动封装

    手动封装我们需要知道,处理哪些东西,这些东西是什么。流程是什么

    同样已MyParcelBean类为例,

    2.1.类的变量定义好了,然后继承接口Parcelable

    2.2.重写以下方法

    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(age);
            dest.writeString(name); 
            dest.writeByte((byte) (sex ? 1 : 0));
    
    }

    writeToParcel是我们需要处理的地方,这边提供了两个参数:Parcel 和flags

    Parcel :是变量的封装,

    flags:是标识

    接下来我们重点讲解Parcel

    1.Parcel 主要提供数据的读写,如果你是什么类型,在读写过程就用什么类型,但是boolean除外,

    2.boolean类型再Parcel中,没有该类型,通过通过byte类型替代

    3.读写的顺序必须对应,如下:

    dest.writeInt(age);
    dest.writeString(name);
    dest.writeByte((byte) (sex ? 1 : 0));

    存的顺序是这样,那么读的顺序也一定要这样,否则数据会异常

    protected MyParaceBean(Parcel in) {
        age = in.readInt();
        name = in.readString();
        sex = in.readByte() != 0;
    }
    

    3.每个parcelable接口都有一个造物者,我们还要实现这个固定写法:

    public static final Creator<MyParaceBean> CREATOR = new Creator<MyParaceBean>() {
        @Override
        public MyParaceBean createFromParcel(Parcel in) {
            return new MyParaceBean(in);
        }
    
        @Override
        public MyParaceBean[] newArray(int size) {
            return new MyParaceBean[size];
        }
    };

    这是固定写法

    4.我们需要实现一个保护类型的构造器,用来读在这数据

    protected MyParaceBean(Parcel in) {
        age = in.readInt();
        name = in.readString();
        sex = in.readByte() != 0;
    }

    5.关于Parcel write写有些要注意的地方

    5.1对象的保存

    如果保存一个对象,这个对象必须也要实现parcelable接口

    在Bean中

    private MyParaceBeanChild child;

    写:

    dest.writeParcelable(child, flags);

    读:

    child = in.readParcelable(MyParaceBeanChild.class.getClassLoader());

    5.2数组数据的保存

    List的数据保存,也是需要在List泛型对象中先实现parcelable的接口,

    在Bena中定义如下:

    private List<MyParaceBeanChild> list;

    写:

    dest.writeTypedList(list);

    读:

    list = in.createTypedArrayList(MyParaceBeanChild.CREATOR);

    5.3Boolean类型

    类型不支持,通过byte来复写,可以参考上面boolean说法

    一般在读写类型中,Parcel数据封装提供了对应的绝大多数类型。

    总结:

    核心点:

    1.构造器读数据

    protected MyParaceBean(Parcel in) {
     
    }

    2.重写方法:写数据

    @Override
    public void writeToParcel(Parcel dest, int flags) {
      
    }

    3.造物标识:CREATOR

    public static final Creator<MyParaceBean> CREATOR = new Creator<MyParaceBean>() {
        @Override
        public MyParaceBean createFromParcel(Parcel in) {
            return new MyParaceBean(in);
        }
    
        @Override
        public MyParaceBean[] newArray(int size) {
            return new MyParaceBean[size];
        }
    };

    只需要处理好这三个地方,其他都是自己的Java逻辑。

  • 相关阅读:
    pytorch深度学习实战lesson25
    【chainlit】使用chainlit部署chatgpt
    【C++笔试强训】第十九天
    【PTA-训练day4】L2-015 互评成绩 + L1-011 A-B
    基于海鸥算法优化的lssvm回归预测-附代码
    快速上手Linux核心命令(九):文件备份与压缩
    02 统计基本概念
    中企出海,用火山引擎DataTester开启增长第一步
    2023年第九届数维杯国际大学生数学建模挑战赛
    指针之野指针系列(2):如何规避野指针
  • 原文地址:https://blog.csdn.net/qq36246172/article/details/125621990