zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android 序列化Parcelable的使用详解

Android 详解 序列化 使用
2023-09-27 14:27:35 时间

背景:

在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逻辑。