版權聲明:本文出自汪磊的博客,轉載請務必注明出處。
一、概述
Android開發的時候,我們時長遇到傳遞對象的需求,但是我們無法將對象的引用傳給Activity或者Fragment,我們需要將這些對象放到一個Intent或者Bundle里面,然后再傳遞,這時候就用到了序列化,所謂序列化就是把Java對象轉換為字節序列並存儲至一個儲存媒介的過程,反序列化就是把字節序列恢復為Java對象的過程。但是我們要知道序列化與反序列化僅處理Java變量而不處理方法,僅對數據進行處理。
二、序列化兩種方式
Android中序列化有兩種方式:Serializable以及Parcelable。其中Serializable是Java自帶的,而Parcelable是安卓專有的。關於二者區別我們最后會總結,先看看怎么使用吧。
三、Serializable方式序列化實例
serializable使用比較簡單,只需要對某個類實現Serializable 接口即可。
Serializable 接口是一種標識接口,某個類實現Serializable 接口,Java便會對這個對象進行序列化操作。
我們編寫Person類:
1 public class Person implements Serializable { 2
3 private static final long serialVersionUID = -3139325922167935911L; 4 // 5 private int age; 6 private String name; 7
8 public int getAge() { 9 return age; 10 } 11
12 public void setAge(int age) { 13 this.age = age; 14 } 15
16 public String getName() { 17 return name; 18 } 19
20 public void setName(String name) { 21 this.name = name; 22 } 23
24 }
很簡單吧,無需過多解釋。接下來我們就將這個類從一個Acticity傳遞到另一個Activity。
MainActivity:
1 public class MainActivity extends Activity { 2
3 // 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 // 9 Person p = new Person(); 10 p.setAge(18); 11 p.setName("wanglei"); 12 // 13 Intent i = new Intent(this, SecondActivity.class); 14 i.putExtra("person", p); 15 startActivity(i); 16
17 } 18 }
SecondActivity:
1 public class SecondActivity extends Activity { 2
3 // 4
5 private static final String TAG = "WL"; 6
7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11
12 Intent intent = getIntent(); 13 Person p=(Person) intent.getSerializableExtra("person"); 14
15 Log.i(TAG, "age = "+p.getAge()); 16 Log.i(TAG, "name = "+p.getName()); 17 } 18 }
以上代碼及其簡單了就不解釋了,運行程序會看到如下打印:

以上就是Serializable方式序列化對象的舉例,真的很簡單,沒有什么多余要解釋的。
四、Parcelable方式序列化實例
關與Parcelable方式實現序列化會比Serializable 方法麻煩一些,大體步驟如下:
1. 實現Parcelable接口
2. 覆寫describeContents方法,默認返回0。
3. 覆寫writeToParcel(Parcel dest, int flags)方法,指定寫入Parcel類的數據。
4. 創建Parcelable.Creator靜態對象,覆寫方法createFromParcel(Parcel in)與newArray(int size)。
Person類:
1 public class Person implements Parcelable { 2
3 // 4 private int age; 5 private String name; 6 private int weight; 7
8 Person(){ 9
10 } 11
12 Person(Parcel in){ 13 age = in.readInt(); 14 name = in.readString(); 15 weight = in.readInt(); 16 } 17
18
19 //序列化時指定將哪些數據寫入Parcel中,注意:寫入順序與讀取順序務必一致
20 @Override 21 public void writeToParcel(Parcel dest, int flags) { 22 // 23 dest.writeInt(age); 24 dest.writeString(name); 25 dest.writeInt(weight); 26 } 27
28 //這里一定要寫上public關鍵字,我測試如果不寫會報異常,此外名字不能改必須為:CREATOR
29 public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() { 30
31 @Override 32 public Person[] newArray(int size) { 33 // 34 return new Person[size]; 35 } 36
37 //反序列化時從Parcel中讀取數據
38 @Override 39 public Person createFromParcel(Parcel source) { 40 //
41 return new Person(source); 42 } 43 }; 44
45 @Override 46 public int describeContents() { 47 //默認返回0即可
48 return 0; 49 } 50
51 // 52 public int getAge() { 53 return age; 54 } 55
56 public void setAge(int age) { 57 this.age = age; 58 } 59
60 public String getName() { 61 return name; 62 } 63
64 public void setName(String name) { 65 this.name = name; 66 } 67
68 public int getWeight() { 69 return weight; 70 } 71
72 public void setWeight(int weight) { 73 this.weight = weight; 74 } 75
76 }
很多注意點都在注釋中寫出來了,仔細看注釋即可。
Persons類:盛放Person類,主要演示如何序列化與反序列化List集合數據,這里似乎有點麻煩了,不過已經這樣寫了就這樣舉例吧。
1 public class Persons implements Parcelable { 2
3 private List<Person> mList; 4
5 Persons() { 6
7 } 8
9 Persons(Parcel in) { 10
11 this.mList = new ArrayList<Person>(); 12 in.readTypedList(mList, Person.CREATOR); 13 } 14
15 @Override 16 public int describeContents() { 17 // 18 return 0; 19 } 20
21 @Override 22 public void writeToParcel(Parcel dest, int flags) { 23 // 24 dest.writeTypedList(mList); 25 } 26
27 public static final Parcelable.Creator<Persons> CREATOR = new Creator<Persons>() { 28
29 @Override 30 public Persons[] newArray(int size) { 31 // 32 return new Persons[size]; 33 } 34
35 @Override 36 public Persons createFromParcel(Parcel source) { 37 // 38 return new Persons(source); 39 } 40 }; 41
42
43 public List<Person> getmList() { 44 return mList; 45 } 46
47 public void setmList(List<Person> mList) { 48 this.mList = mList; 49 } 50
51 }
Persons主要演示如何反序列化集合類數據,如11,12行代碼。
MainActivity:
1 public class MainActivity extends Activity { 2
3 // 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 // 9 Person p1 = new Person(); 10 p1.setAge(18); 11 p1.setName("wanglei1"); 12 p1.setWeight(130); 13 // 14 Person p2 = new Person(); 15 p2.setAge(28); 16 p2.setName("wanglei2"); 17 p2.setWeight(125); 18 // 19 List<Person> mList = new ArrayList<Person>(); 20 mList.add(p1); 21 mList.add(p2); 22 // 23 Persons mPersons = new Persons(); 24 mPersons.setmList(mList); 25 // 26 Intent i = new Intent(this, SecondActivity.class); 27 i.putExtra("persons", mPersons); 28 startActivity(i); 29
30 } 31 }
也很簡單吧,沒什么要特別說明的。
SecondActivity:
1 public class SecondActivity extends Activity { 2
3 // 4
5 private static final String TAG = "WL"; 6
7 @Override 8 protected void onCreate(Bundle savedInstanceState) { 9 super.onCreate(savedInstanceState); 10 setContentView(R.layout.activity_main); 11
12 Intent intent = getIntent(); 13 Persons ps = (Persons) intent.getParcelableExtra("persons"); 14 List<Person> pList = ps.getmList(); 15 for (int i = 0; i < pList.size(); i++) { 16 Person p = pList.get(i); 17 Log.i(TAG, "age = " + p.getAge()); 18 Log.i(TAG, "name = " + p.getName()); 19 Log.i(TAG, "weight = " + p.getWeight()); 20 } 21
22 } 23 }
主要就是通過intent.getParcelableExtra獲取序列化的對象,也很簡單。
運行程序結果如下:

數據傳遞成功,如果仔細看上面例子應該對Parcelable方式實現序列化有了一定的了解,貌似寫起來會比Serializable方式復雜一些,很多都是模板代碼,照着寫就是了,那這兩種方式有什么區別呢?
五、兩種序列化方式區別
兩者區別在於存儲媒介的不同。
Serializable使用IO讀寫存儲在硬盤上。序列化過程使用了反射技術,並且期間產生臨時對象。優點代碼少。
Parcelable是直接在內存中讀寫,我們知道內存的讀寫速度肯定優於硬盤讀寫速度,所以Parcelable序列化方式性能上要優於Serializable方式很多。但是代碼寫起來相比Serializable方式麻煩一些。
通過比較發現,性能與簡便我們只能選其一,大多數情況下使用Serializable也是沒什么問題的,但是還是建議大家使用Parcelable方式實現序列化,畢竟性能好很多,其實也沒多麻煩。
好了,本文到此結束,希望對你有一些幫助。
聲明:文章將會陸續搬遷到個人公眾號,以后文章也會第一時間發布到個人公眾號,及時獲取文章內容請關注公眾號

