Android序列化

一、什么叫序列化?

序列化就是将对象的状态信息转换为可以存储或传输的形式的过程。我们有时候需要进行对象的传输,如果要进行对象的传输我们必须得实现序列化才行。在Android里面实现序列化的方式一般来说有SerializableParcelable两种方式,下面我们通过一个简单的小例子来了解下这两种方式吧。

1、Serializable

Serializable是Java提供的一种序列化的方式,使用起来也很简单,直接让我们的实体类实现Serializable接口就可以了,下面我们来新建一个SerializationTest项目开始吧。

首先我们新建一个Student类,然后实现Serializable接口即可。代码如下:

public class Student implements Serializable {
    
    private static final long serialVersionUID = 2198186818507399576L;
    
    private String mName;
    private int mAge;

    public Student(String name, int age) {
        mName = name;
        mAge = age;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public int getAge() {
        return mAge;
    }

    public void setAge(int age) {
        mAge = age;
    }
}

在这个类里面我们定义了两个全局变量,和普通的实体类没什么两样,唯一的区别是多了个serialVersionUID这个常量,至于这个常量是用来干嘛的,稍后我们再做解释。

下面我们再新建一个SecondActivity活动,然后在MainActivity写一个跳转方法,代码如下:

btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Student student = new Student("张三", 20);
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                intent.putExtra("student", student);
                startActivity(intent);
            }
        });

接下来我们再SecondActivity中接收这个参数:

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = "SecondActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = getIntent();
        if (intent != null) {
            Student student = (Student) intent.getSerializableExtra("student");
            Log.d(TAG, "name is: " + student.getName());
            Log.d(TAG, "age is: " + student.getAge());
        }
    }
}

最后我们得到了我们想要的数据,这就是Serializable的基本使用方式。

下面来说一下serialVersionUID的作用,这个值的作用主要是在反序列化的时候起作用,在我们反序列化Java对象的时候必须提供该对象的class文件,如果我们不显示定义这个值的话,系统会根据我们类的信息去自动生成serialVersionUID。有时候我们增加了成员变量或者减少了成员变量,如果没有显示定义serialVersionUID值,系统就会新生成一个serialVersionUID,就会导致serialVersionUID值不一致,最后导致反序列化失败。所以我们在使用Serializable的时候最好手动定义serialVersionUID值,这里值得要注意的是如果我们的类结构发生变化,比如类名改变或者成员变量类型发生变化,这个时候就算显示定义了这个值也会反序列化失败。

1、Parcelable

Parcelable是Android特有的一种序列化方式,使用起来会稍微复杂一点,依旧用上面那个例子来实现一下吧:

public class Student implements Parcelable {

    private String mName;
    private int mAge;

    public Student(String name, int age) {
        mName = name;
        mAge = age;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public int getAge() {
        return mAge;
    }

    public void setAge(int age) {
        mAge = age;
    }


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

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

    protected Student(Parcel in) {
        this.mName = in.readString();
        this.mAge = in.readInt();
    }

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

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

上面的代码稍微有点复杂,我们先来简单的解释一下吧,当我们序列化的时候会走writeToParcel()这个方法,把对象写入Parcel对象里面去,反序列化则是通过CREATOR来完成的;describeContents()这个方法在通常情况下都是返回0,我们一般不用去管。接下来再将SecondActivity中稍微改动下就可以啦。

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = "SecondActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = getIntent();
        if (intent != null) {
            Student student = intent.getParcelableExtra("student");
            Log.d(TAG, "name is: " + student.getName());
            Log.d(TAG, "age is: " + student.getAge());
        }
    }
}

下面来说下这两种序列化方式的区别:

Serializable

优点:使用方式简单。

缺点:资源消耗稍大。

Parcelable

优点:资源消耗小。

缺点:使用方式复杂。

总结:当我们在内存间进行对象传输时,使用Parcelable方式。如果要在存储或网络上进行传输时,使用Serializable。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章