Android序列化方式Serializable和Parcelable
前言
在介紹Serializable和Parcelable兩種序列化方式之前,我們先來了解下什麼是序列化,什麼是反序列化,為什麼要序列化?
序列化:
把物件轉換成位元組系列的過程叫做物件的序列化。
反序列化:
把位元組序列恢復成物件的過程叫做物件的反序列化。
序列化的主要用途:
(1)把物件永久的存放在磁碟中,在Android系統中就是存放在sdcard中,通常是存放在一個檔案中。
(2)在網路中傳輸物件。
例如:在web伺服器中的session物件,一個使用者訪問,就會有一個session物件。當數十萬的使用者併發訪問,就會產生數十萬個session物件,記憶體一時承受不住那麼多物件,web容器就會把session物件序列化成位元組序列存放到磁碟中,當需要用到的時候,在恢復成物件。
在跨程序通訊的時候,因為資料是在網路中傳輸的,網路傳輸只能傳輸位元組序列,所以需要把物件序列化成位元組序列進行傳輸。
Serializable
Serializable是Java提供的序列化介面,下面介紹一下使用方法。
public class UserDto implements Serializable { private static final long serialVersionUID = -7007857824834322776L; private String username; private String password; public UserDto(String username, String password) { this.username = username; this.password = password; } public UserDto() { } public static long getSerialVersionUID() { return serialVersionUID; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
首先在實體類中實現Serializable 介面,然後宣告serialVersionUID 變數。接下來我們介紹如何把物件序列化到sdcard中的檔案中以及把物件反序列化出來。
序列化到檔案中:
ivEtxt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { UserDto userDto = new UserDto("admin", "123456"); try { ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt")); stream.writeObject(userDto); stream.close(); Log.e(TAG, "onClick: 寫入成功"); } catch (Exception e) { Log.e(TAG, "onClick: "+e.getMessage() ); } }
反序列化成物件:
ivEtxt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //UserDto userDto = new UserDto("admin", "123456"); try { //ObjectOutputStream stream = //new ObjectOutputStream(new FileOutputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt")); //stream.writeObject(userDto); //stream.close(); //Log.e(TAG, "onClick: 寫入成功"); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FileUtils.getCachFilePath(MainActivity.this)+"user.txt")); UserDto userDto = (UserDto) inputStream.readObject(); inputStream.close(); Log.e(TAG, "onClick: "+userDto.getUsername()+":"+userDto.getPassword() ); } catch (Exception e) { Log.e(TAG, "onClick: "+e.getMessage() ); } } });
Parcelable
以上我們介紹了Serializable,Java中的序列化方式,現在我們來介紹下Parcelable,Parcelable是在AndroidSdk中。接下來我們介紹使用方法:
package com.mujin.keji.myapplication; import android.os.Parcel; import android.os.Parcelable; public class UserBean implements Parcelable { private String username; private String password; public UserBean() { } public UserBean(String username, String password) { this.username = username; this.password = password; } protected UserBean(Parcel in) { username = in.readString(); password = in.readString(); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(username); dest.writeString(password); } public static final Creator<UserBean> CREATOR = new Creator<UserBean>() { @Override public UserBean createFromParcel(Parcel in) { return new UserBean(in); } @Override public UserBean[] newArray(int size) { return new UserBean[size]; } }; }
實體類實現Parcelable介面,並實現相應的方法。看上面的程式碼所示。我們看到使用Parcelable方式進行序列化,需要重寫幾個方法,和成員變數。其中序列化功能由writeToParcel完成,反序列化由CREATOR 完成,describeContents用來描述內容。
Serializable和Parcelable應該怎麼選擇?
既然Serializable和Parcelable都可以序列化,都可以用於Intent傳輸資料,那麼二者怎麼選擇呢?首先Serializable是Java中的介面,序列化和反序列過程都需要大量的I/O操作,開銷很大。而Parcelable是Android中的序列化方式,更加適用於Android平臺。它的缺點就是適用起來比較麻煩,但是使用的效率很高。那麼我們應該怎麼選擇呢?
一般情況下我們首先選擇Parcelable,Parcelable主要用於在記憶體上的序列化,比如在Intent之間傳輸資料的時候,可以用Parcelable。如果要在磁碟中或者網路傳輸的序列化,也可以用Parcelable,但是操作很麻煩,這個時候我們應該選擇Serializable。