生活随笔
收集整理的這篇文章主要介紹了
一人一猫旅行记之浅析序列化及原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在Activity跳轉的時候,往往需要傳遞一個對象。不像String等基本類型,可以直接通過Intent的putExtra方法將數據加到Bundle中,換句話說對象并不是計算機可以識別的類型。
這樣的話就涉及到了一個概念,序列化。 什么是序列化呢?序列化就是將對象轉成可以存儲或者傳遞的形式的過程,反序列化也是一個相反的過程,也就是將序列化后的數據轉換成對象的一個過程。
Java與安卓分別提供了一種序列化的方法(Serializable和Parcelable) 那么二有什么區別呢? 1,Serializable會涉及到反射,產生大量的臨時變量,這會引起系統頻繁的GC 2,Serializable由JDK完成轉換,而Parcelable則是自己完成序列化和反序列化,這就導致前者的效率要遠低于后者。安卓之所以設計Parcelable的初衷就是Serializable效率過慢,為了在組件之間或者不同APP之間提高數據的傳輸速度,才設計了Parcelable。 3,如果當數據要存儲在磁盤而不是內存中,Parcelable無法保證在外部環境發生變化時的連續性。 因此,在Android的組件或者APP之間傳遞數據,選擇Parcelable。如果想要保存數據或者在網絡上傳輸則選擇Serializable。
二者在使用上也有很大的區別: 首先,對于Serializable來說使用非常簡單,只需要讓對象實現Serializable接口即可 我們可以看到Serializable這個接口是一個空的接口,這是怎么回事呢? 其實Serializable只是增加一個標識,在寫入或者讀取的時候會根據這個標識進行對應的處理,我們看到上面的注釋涉及到幾個類,咱們就看一下ObjectOutputStream中的源碼。
private void writeObject0(Object obj, boolean unshared)throws IOException{<-省略部分代碼->// ----- BEGIN android -----if (obj instanceof Class) {writeClass((Class) obj, unshared);} else if (obj instanceof ObjectStreamClass) {writeClassDesc((ObjectStreamClass) obj, unshared);// ----- END android -----} else if (obj instanceof String) {writeString((String) obj, unshared);} else if (cl.isArray()) {writeArray(obj, desc, unshared);} else if (obj instanceof Enum) {writeEnum((Enum) obj, desc, unshared);} else if (obj instanceof Serializable) {writeOrdinaryObject(obj, desc, unshared);} else {if (extendedDebugInfo) {throw new NotSerializableException(cl.getName() + "\n" + debugInfoStack.toString());} else {throw new NotSerializableException(cl.getName());}}} finally {depth--;bout.setBlockDataMode(oldMode);}}
從上面的代碼應該可以明白,如果一個類加了Serializable標識,則會調用writeOrdinaryObject(obj, desc, unshared); 如果繼續往下閱讀代碼的話,會走到如下的方法中:
private void writeSerialData(Object obj, ObjectStreamClass desc)throws IOException{ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();for (int i = 0; i < slots.length; i++) {ObjectStreamClass slotDesc = slots[i].desc;if (slotDesc.hasWriteObjectMethod()) {PutFieldImpl oldPut = curPut;curPut = null;SerialCallbackContext oldContext = curContext;if (extendedDebugInfo) {debugInfoStack.push("custom writeObject data (class \"" +slotDesc.getName() + "\")");}try {curContext = new SerialCallbackContext(obj, slotDesc);bout.setBlockDataMode(true);slotDesc.invokeWriteObject(obj, this);bout.setBlockDataMode(false);bout.writeByte(TC_ENDBLOCKDATA);} finally {curContext.setUsed();curContext = oldContext;if (extendedDebugInfo) {debugInfoStack.pop();}}curPut = oldPut;} else {defaultWriteFields(obj, slotDesc);}}}
看到這相信就知道為什么Serializable的效率會低了吧?
然后,對于Parcelable來說,它的使用相對比較復雜,因為它需要我們手動實現序列化與反序列化的方法。 我們創建一個Person.java,實現Parcelable,會提示增加兩個方法和Parcelable的實現,其實分別對應Parcelable的三個過程(描述、序列化、反序列化)
@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeInt(age);dest.writeString(name);}@Overridepublic int describeContents() {return 0;}
上面是要實現的兩個方法,describeContents一般不需要處理,如果有一些需要特殊處理的數據的話則返回1。writeToParcel則是序列化的過程。
public static final Creator<Person> CREATOR = new Creator<Person>() {@Overridepublic Person createFromParcel(Parcel in) {return new Person(in);}@Overridepublic Person[] newArray(int size) {return new Person[size];}};
createFromParcel中返回一個Person對象,也就是反序列化的實現。
在前面咱們提到了序列化跟反序列化只是一個過程,所以無論Serializable還是Parcelable只是一種實現方式,我們還可以通過很多其他的方式來實現,比如JSON、XML,甚至用字符串也可以實現。
總結
以上是生活随笔 為你收集整理的一人一猫旅行记之浅析序列化及原理 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。