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。

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