Android 内存对象序列化(实现Intent传递更多类型的数据(对象为例))

序列化(Sreilaizbale)定义:

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

简单来说:

序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

为什么需要序列化:

知道前面的序列化定义,内存对象什么需要实现序列化呢?

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

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

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

实现序列化的两种方式:

那么我们如何实现序列化的操作呢?在Android开发中我们实现序列化有两种方式:

  • 实现Serializable接口

  • 实现parcelable接口

两种序列化方式的区别:

都知道在Android studio中序列化有两种方式:serializable与parcelable。那么这两种实现序列化的方式有什么区别呢?下面是这两种实现序列化方式的区别:

  1. Serializeble是java的序列化方式,Parcelable是Android特有的序列化方式;

  2. 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。

  3. Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

  4. Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable。

最后还有一点就是Serializeble序列化的方式比较简单,直接集成一个接口就好了,而parcelable方式比较复杂,不仅需要集成Parcelable接口还需要重写里面的方法。

为什么要实现对象序列化:

我们知道Android开发过程中不同Activity之间传输数据可以通过Intent对象的putExtra方法传递,对于java的八大基本数据类型(char int float double long short boolean byte)传递是没有问题的,但是如果传递比较复杂的对象类型(比如对象,比如集合等),那么就可能存在问题,就需要实现数据对象数据序列化。

对象实现序列化的实例:

通过实现Serializable接口实现序列化:

上面介绍了那么多概念上的知识,下面我们就具体看一下如何通过这两种方式实现序列化,我们首先看一下如何通过实现Serializable接口实现序列化,通过实现Serializable接口实现序列化,只需要简单的实现Serialiizable接口即可。通过实现Serializable接口就相当于标记类型为序列化了,不需要做其他的操作了。

import java.io.Serializable;

public class PersonOne implements Serializable {

    private static final long serialVersionUID = -6009011239477487992L;

    private String name;

    private int age;

    private int id;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}

可以发现我们定义了一个普通的实体PersonOne类,并设置了三个成员属性以及各自的set,get方法,然后我们就只是简单的实现了Serializable接口就相当于将该类序列化了,当我们在程序中传输该类型的对象的时候就没有问题了。

现在我们来传递它:

PersonOne personOne = new PersonOne();
personOne.setName("Tom");
personOne.setAge(10);
personOne.setId(1);
Intent intentOne = new Intent(MainActivity.this,SecondActivity.class);
intentOne.putExtra("person_data", personOne);
startActivity(intentOne);

接收它:

PersonOne personOne = (PersonOne) getIntent()
        .getSerializableExtra("person_data");

Toast.makeText(this,"Id = "+personOne.getId()+" Name = "
        + personOne.getName() + " Age = "+ personOne.getAge(),Toast.LENGTH_LONG).show();

并且我们在Person类中定义了一个属性为serialVersionUID的成员变量,这个成员变量是做什么的呢? 
在Java中,软件的兼容性是一个大问题,尤其在使用到对象串行性的时候,那么在某一个对象已经被串行化了,可是这个对象又被修改后重新部署了,那么在这种情况下, 用老软件来读取新文件格式虽然不是什么难事,但是有可能丢失一些信息。 
serialVersionUID来解决这些问题,新增的serialVersionUID必须定义成下面这种形式:

private static final long serialVersionUID = -6009011239477487992L;

其中数字后面加上的L表示这是一个long值。 通过这种方式来解决不同的版本之间的串行化的问题。

简单来说就是用serialVersionUID标识class类的版本,当序列化的class源文件发生变化时,反序列化的一端由于该标识不一致会反序列化失败,进而保证了两端源文件的一致性。

设置Android studio实现Serializable自动生成serialVersionUID步骤:

1、File–>Settings–>Editor–>Inspections–>Java–>Serialization issues–>Serializable class without ‘serialVersionUID’ 勾选中该选项即可。

2、进入实现了Serializable中的类,选中类名,Alt+Enter弹出提示,然后直接导入完成

通过实现Parcelable接口实现序列化:

然后我们在看一下通过实现Parcelable接口来实现序列化的方式,通过实现Parcelable接口实现序列化相当于实现Serialiable接口稍微复杂一些,因为其需要实现一些特定的方法,下面我们还是以我们定义的PersonTwo类为例子,看一下如果是实现Parcelable接口具体是如何实现的:

import android.os.Parcel;
import android.os.Parcelable;

public class PersonTwo implements Parcelable {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    private String name;

    private int age;


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
    }

    public PersonTwo() {
    }

    protected PersonTwo(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }

    public static final Creator<PersonTwo> CREATOR = new Creator<PersonTwo>() {
        @Override
        public PersonTwo createFromParcel(Parcel source) {
            return new PersonTwo(source);
        }

        @Override
        public PersonTwo[] newArray(int size) {
            return new PersonTwo[size];
        }
    };


}

可以发现当我们通过实现Parcelable接口实现序列化还需要重写里面的成员方法,并且这些成员方法的写法都比较固定。

传递它:

PersonTwo personTwo = new PersonTwo();
personTwo.setName("Nice");
personTwo.setAge(20);
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("person_two_data",personTwo);
startActivity(intent);

接收它:

PersonTwo personTwo = getIntent().getParcelableExtra("person_two_data");

Toast.makeText(this,"Name = "+personTwo.getName()+
        " Age = "+personTwo.getAge(),Toast.LENGTH_LONG).show();

实现Parcelable序列化的Android studio插件:

顺便说一下最近发现一个比较不错的Parcelable序列化插件。下面就来看一下如何安装使用该插件。

打开Android studio –> settings –> Plugins –> 搜索Parcelable –> Install –> Restart,这样安装好了Parcelable插件;

然后你就可以在源文件中右键 –> Generate… –> Parcelable

猜你喜欢

转载自blog.csdn.net/qq_36607515/article/details/81545405