Parcelable簡單介紹
介紹Parcelable不得不先提一下Serializable接口,Serializable是Java為我們提供的一個標準化的序列化接口,那什么是序列化呢? —-?簡單來說就是將對象轉(zhuǎn)換為可以傳輸?shù)亩M制流(二進制序列)的過程,這樣我們就可以通過序列化,轉(zhuǎn)化為可以在網(wǎng)絡傳輸或者保存到本地的流(序列),從而進行傳輸數(shù)據(jù)?,那反序列化就是從二進制流(序列)轉(zhuǎn)化為對象的過程.
Parcelable是Android為我們提供的序列化的接口,Parcelable相對于Serializable的使用相對復雜一些,但Parcelable的效率相對Serializable也高很多,這一直是Google工程師引以為傲的,有時間的可以看一下Parcelable和Serializable的效率對比號稱快10倍的效率
Parcelable接口的實現(xiàn)類是可以通過Parcel寫入和恢復數(shù)據(jù)的,并且必須要有一個非空的靜態(tài)變量 CREATOR, 而且還給了一個例子,這樣我們寫起來就比較簡單了,但是簡單的使用并不是我們的最終目的
通過查看Android源碼中Parcelable可以看出,Parcelable實現(xiàn)過程主要分為序列化,反序列化,描述三個過程,下面分別介紹下這三個過程
Parcel的簡介
在介紹之前我們需要先了解Parcel是什么?Parcel翻譯過來是打包的意思,其實就是包裝了我們需要傳輸?shù)臄?shù)據(jù),然后在Binder中傳輸,也就是用于跨進程傳輸數(shù)據(jù)
簡單來說,Parcel提供了一套機制,可以將序列化之后的數(shù)據(jù)寫入到一個共享內(nèi)存中,其他進程通過Parcel可以從這塊共享內(nèi)存中讀出字節(jié)流,并反序列化成對象,下圖是這個過程的模型。

Parcel可以包含原始數(shù)據(jù)類型(用各種對應的方法寫入,比如writeInt(),writeFloat()等),可以包含Parcelable對象,它還包含了一個活動的IBinder對象的引用,這個引用導致另一端接收到一個指向這個IBinder的代理IBinder。
Parcelable通過Parcel實現(xiàn)了read和write的方法,從而實現(xiàn)序列化和反序列化??梢钥闯霭烁鞣N各樣的read和write方法,最終都是通過native方法實現(xiàn)

Parcelable的三大過程介紹(序列化、反序列化、描述)
到這里,基本上關系都理清了,也明白簡單的介紹和原理了,接下來在實現(xiàn)Parcelable之前,介紹下實現(xiàn)Parcelable的三大流程?
首先寫一個類實現(xiàn)Parcelable接口,會讓我們實現(xiàn)兩個方法

1.3.1 描述
其中describeContents就是負責文件描述,首先看一下源碼的解讀

通過上面的描述可以看出,只針對一些特殊的需要描述信息的對象,需要返回1,其他情況返回0就可以
1.3.2 序列化
我們通過writeToParcel方法實現(xiàn)序列化,writeToParcel返回了Parcel,所以我們可以直接調(diào)用Parcel中的write方法,基本的write方法都有,對象和集合比較特殊下面單獨講,基本的數(shù)據(jù)類型除了boolean其他都有,Boolean可以使用int或byte存儲
1.3.3 反序列化
反序列化需要定義一個CREATOR的變量,上面也說了具體的做法,這里可以直接復制Android給的例子中的,也可以自己定義一個(名字千萬不能改),通過匿名內(nèi)部類實現(xiàn)Parcelable中的Creator的接口
Parcelable的實現(xiàn)和使用
根據(jù)上面三個過程的介紹,Parcelable就寫完了,就可以直接在Intent中傳輸了,可以自己寫兩個Activity傳輸一下數(shù)據(jù)試一下,其中一個putExtra另一個getParcelableExtra即可
這里實現(xiàn)Parcelable也很簡單
1.寫一個類實現(xiàn)Parcelable然后alt+enter 添加Parcelable所需的代碼塊,AndroidStudio會自動幫我們實現(xiàn)(這里需要注意如果其中包含對象或集合需要把對象也實現(xiàn)Parcelable)

Parcelable中對象和集合的處理
如果實現(xiàn)Parcelable接口的對象中包含對象或者集合,那么其中的對象也要實現(xiàn)Parcelable接口?
寫入和讀取集合有兩種方式,?
一種是寫入類的相關信息,然后通過類加載器去讀取, –> writeList | readList?
二是不用類相關信息,創(chuàng)建時傳入相關類的CREATOR來創(chuàng)建 –> writeTypeList | readTypeList | createTypedArrayList?
第二種效率高一些
一定要注意如果有集合定義的時候一定要初始化 like this –>
public ArrayList authors = new ArrayList<>();
Parcelable和Serializable的區(qū)別和比較
Parcelable和Serializable都是實現(xiàn)序列化并且都可以用于Intent間傳遞數(shù)據(jù),Serializable是Java的實現(xiàn)方式,可能會頻繁的IO操作,所以消耗比較大,但是實現(xiàn)方式簡單 Parcelable是Android提供的方式,效率比較高,但是實現(xiàn)起來復雜一些 , 二者的選取規(guī)則是:內(nèi)存序列化上選擇Parcelable, 存儲到設備或者網(wǎng)絡傳輸上選擇Serializable(當然Parcelable也可以但是稍顯復雜)