日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一人一猫旅行记之浅析序列化及原理

發布時間:2023/12/16 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一人一猫旅行记之浅析序列化及原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在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,甚至用字符串也可以實現。

總結

以上是生活随笔為你收集整理的一人一猫旅行记之浅析序列化及原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。