序列化是指把數據從快速、高效的內部表現方式轉換成可在網絡上持久存儲或傳輸的形式。把數據轉換成序列化形式通常稱為對該數據執行marshaling(編組)。把數據轉換回其活躍的、在內存內的表現形式即稱為反序列化(deserializing)或unmarshaling。
究竟應該如何對數據執行序列化取決於其序列化的原因。例如,為了網絡傳輸執行的數據序列化,在傳輸過程中的數據可能是不可讀的。但是,對於保存在數據庫中的序列化數據,如果數據的表現形式使得編寫SQL查詢簡單容易,那將是很有用的。對於網絡傳輸,序列化可能是二進制形式;對於數據庫存儲,則可能是帶標籤的文本形式。Android環境提供了4種常見的序列化使用方式。
生命週期管理
和較大的設備(如筆記本和台式機)不同,不能指望Android設備在應用僵死時,能夠把應用切換到快速的備用存儲上。相反,Android框架提供了一種對象,稱為Bundle。當應用掛起時,它把狀態寫入Bundle。當重新創建應用時,Android框架能夠提供一份和該應用啟動時相同的Bundle副本。應用必須能夠對其掛起期間想要保存的信息都能夠執行序列化,並且把序列化後的版本保存到Bundle中。
持久性
除了在Bundle中所保存的即時應用狀態,絕大多數應用都管理著一些持久性數據存儲。這些數據很可能是封裝在ContentProvider中的SQLite數據庫中。應用必須能夠在對像數據的內部表現和這些對像在數據庫中的表現之間進行切換。在較大型的系統中,這個過程稱為對像關係映射object relational mapping或ORM,其由類似Hibernate和iBATIS這樣的框架支持。Android的本地數據存儲更簡單和輕量級,第9章會對它進行介紹。
本地進程間通信
Android框架提倡的架構支持把較大的單個應用分解成小的組件:一組UI、內容提供者和服務。這些組件無法相互訪問對方的內存空間,必須使用序列化消息在進程間傳遞。Android為此提供了一個高度優化的工具:AIDL。
網絡通信
網絡通信是移動設備極其重要的一個功能。支持連接到互聯網並使用互聯網上各種各樣的服務也正是Android要實現的。應用必須能夠處理外部服務要求的各種協議,包括把內部信息翻譯成對這些服務的查詢,並把服務返回的結果重新翻譯回來。
以下各節描述了為實現這些目標,會使用到的各個相關的類。
Java序列化
Java通過Serializable標記接口,以及一對序列化類型ObjectOutputStream和ObjectInputStream,來定義其序列化框架。因為大多數情況下Java序列化都能夠正常工作,即使經驗豐富的Java程序員可能都沒有意識到其複雜性。關於Java序列化的探討顯然超出了本書的範疇。Josh Bloch在他的著作《Effective Java》。 [1](Prentice Hall出版社出版)一書中,以接近10%的篇幅詳細探討了Java序列化框架及如何正確使用它。即使你並不想用Java框架,其關於Java序列化一節的探討也值得一讀。
Android支持Java序列化。舉個例子,Bundle類有兩個方法putSerializable和getSerializable,它們分別執行把Java Serializable對像插入Bundle中以及從Bundle中獲取Java Serializable對象。例如:
public class JSerialize extends Activity { public static final String APP_STATE = \"com.oreilly.android.app.state\"; private static class AppState implements Serializable { // definitions, getters and setters // for application state parameters here. // ... } private AppState applicationState; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedAppState) { super.onCreate(savedAppState); applicationState = (null == savedAppState) ? new AppState(/* ... */) : (AppState) savedAppState.getSerializable(APP_STATE); setContentView(R.layout.main); // ... } /** * @see android.app.Activity#onSaveInstanceState(android.os.Bundle) */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putSerializable(APP_STATE, applicationState); } }
在這個例子中,應用以Serializable對象的方式保存了一些全局狀態信息——可能是最近使用項的列表。當要暫停一個JSerialize activity,而在內存中執行另一個activity時,Android框架會調用JSerialize的回調方法onSaveInstanceState,傳遞一個Bundle對象。回調方法使用Bundle.putSerializable把對象的狀態保存到Bundle中。當恢復JSerialize方法時,onCreate方法使用getSerializable方法從Bundle中獲取狀態。
[1] 中文版已由機械工業出版社出版,書號為978-7-111-25583-3。