探索Android中的Parcel機制(上)

一.先從Serialize提及java

         咱們都知道JAVA中的Serialize機制,譯成串行化、序列化……,其做用是能將數據對象存入字節流其中,在需要時又一次生成對象。主要應用是利用外部存儲設備保存對象狀態,以及經過網絡傳輸對象等。android

 

二.Android中的新的序列化機制git

         Android系統中,定位爲針對內存受限的設備,所以對性能要求更高,另外系統中採用了新的IPC(進程間通訊)機制,一定要求使用性能更出色的對象傳輸方式。在這種環境下,Parcel被設計出來,其定位就是輕量級的高效的對象序列化和反序列化機制。express

 

三.Parcel類的背後apache

         Framework中有parcel類,源代碼路徑是:cookie

Frameworks/base/core/java/android/os/Parcel.java網絡

典型的源代碼片段例如如下:session

 

 

  app

 

         從中咱們看到,從這個源程序文件裏咱們看不到真正的功能是怎樣實現的,必須透過JNI往下走了。因而,Frameworks/base/core/jni/android_util_Binder.cpp中找到了線索less

 

  

         從這裏咱們可以獲得的信息是函數的實現依賴於Parcel指針,所以還需要找到Parcel的類定義,注意,這裏的類已是用C++語言實現的了。

         找到Frameworks/base/include/binder/parcel.hFrameworks/base/libs/binder/parcel.cpp。最終找到了最終的實現代碼了。

         有興趣的朋友可以本身讀一下,不難理解,這裏把主要的思路總結一下:

1.       整個讀寫全是在內存中進行,主要是經過malloc()realloc()memcpy()等內存操做進行,因此效率比JAVA序列化中使用外部存儲器會高很是多;

2.       讀寫時是4字節對齊的,可以看到#define PAD_SIZE(s) (((s)+3)&~3)這句宏定義就是在作這件事情;

3.       假設預分配的空間不夠時newSize = ((mDataSize+len)*3)/2;會一次多分配50%

4.       對於普通數據,使用的是mData內存地址,對於IBinder類型的數據以及FileDescriptor使用的是mObjects內存地址。後者是經過flatten_binder()unflatten_binder()實現的,目的是反序列化時讀出的對象就是原對象而不用又一次new一個新對象。

 

好了,這就是Parcel背後的動做,全是在一塊內存裏進行讀寫操做,就不囉嗦了,把parcel的代碼貼在這供沒有源代碼的朋友參考吧。接下來我會用一個小DEMO演示一下Parcel類在應用程序中的使用,詳見《探索Android中的Parcel機制(下)》。

 

 

 

         本文的源代碼使用的是Android 2.1版本號。

 

——歡迎轉載,請註明出處 http://blog.csdn.net/caowenbin ——

相關文章
相關標籤/搜索