序列化Serializable和Parcelable的理解和區(qū)別

一卡者、android為什么要序列化熔恢?什么是序列化,怎么進行序列化

1.為什么要了解序列化犁珠?—— 進行Android開發(fā)的時候,無法將對象的引用傳給Activities或者Fragments互亮,我們需要將這些對象放到一個Intent或者Bundle里面犁享,然后再傳遞。

2.什么是序列化 —— 序列化豹休,表示將一個對象轉換成可存儲或可傳輸的狀態(tài)炊昆。序列化后的對象可以在網絡上進行傳輸,也可以存儲到本地威根。

3.怎么通過序列化傳輸對象凤巨?

Android中Intent如果要傳遞類對象,可以通過兩種方式實現洛搀。

方式一:Serializable敢茁,要傳遞的類實現Serializable接口傳遞對象,

方式二:Parcelable留美,要傳遞的類實現Parcelable接口傳遞對象彰檬。

Serializable(Java自帶):

Serializable是序列化的意思伸刃,表示將一個對象轉換成可存儲或可傳輸的狀態(tài)。序列化后的對象可以在網絡上進行傳輸僧叉,也可以存儲到本地奕枝。

Parcelable(android 專用):

除了Serializable之外,使用Parcelable也可以實現相同的效果瓶堕,

不過不同于將對象進行序列化隘道,Parcelable方式的實現原理是將一個完整的對象進行分解,

而分解后的每一部分都是Intent所支持的數據類型郎笆,這樣也就實現傳遞對象的功能了谭梗。

實現Parcelable的作用

1)永久性保存對象,保存對象的字節(jié)序列到本地文件中宛蚓;

2)通過序列化對象在網絡中傳遞對象激捏;

3)通過序列化在進程間傳遞對象。

選擇序列化方法的原則

1)在使用內存的時候凄吏,Parcelable比Serializable性能高远舅,所以推薦使用Parcelable。

2)Serializable在序列化的時候會產生大量的臨時變量痕钢,從而引起頻繁的GC图柏。

3)Parcelable不能使用在要將數據存儲在磁盤上的情況,因為Parcelable不能很好的保證數據的持續(xù)性在外界有變化的情況下任连。盡管Serializable效率低點蚤吹,但此時還是建議使用Serializable 。

應用場景

需要在多個部件(Activity或Service)之間通過Intent傳遞一些數據随抠,簡單類型(如:數字裁着、字符串)的可以直接放入Intent。復雜類型必須實現Parcelable接口拱她。

二二驰、利用java自帶的Serializable 進行序列化的例子

弄一個實體類 Person,利用Java自帶的Serializable進行序列化

packagecom.amqr.serializabletest.entity;importjava.io.Serializable;/**


*/public class Person implements Serializable {private static final long serial VersionUID =7382351359868556980L;

private String name;

private int age;

public int getAge(){returnage;? ? }

public void setAge(intage){this.age = age;? ? }

public StringgetName(){returnname;? ? }

public void setName(String name){this.name = name;? ? }}

使用秉沼,MainActivity和SecondActivity結合使用

MainActivity

publicclassMainActivityextendsActivity{privateTextView mTvOpenNew;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){?

?Intent open =newIntent(MainActivity.this,SecondActivity.class);?

?Person person =newPerson();?

?person.setName("一去二三里");?

?person.setAge(18);

// 傳輸方式一桶雀,intent直接調用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 傳輸方式二,intent利用putExtras(注意s)傳入bundle/**

? ? ? ? ? ? ? ? Bundle bundle = new Bundle();

? ? ? ? ? ? ? ? bundle.putSerializable("bundle_ser",person);

? ? ? ? ? ? ? ? open.putExtras(bundle);

? ? ? ? ? ? ? ? */startActivity(open);? ? ? ? ? ? }? ? ? ? });? ? }}

* 進行Android開發(fā)的時候氧猬,我們都知道不能將對象的引用傳給Activities或者Fragments背犯,

* 我們需要將這些對象放到一個Intent或者Bundle里面坏瘩,然后再傳遞盅抚。

*

*

* Android中Intent如果要傳遞類對象,可以通過兩種方式實現倔矾。

* 方式一:Serializable妄均,要傳遞的類實現Serializable接口傳遞對象柱锹,

* 方式二:Parcelable,要傳遞的類實現Parcelable接口傳遞對象丰包。

*

* Serializable(Java自帶):

* Serializable是序列化的意思禁熏,表示將一個對象轉換成可存儲或可傳輸的狀態(tài)。序列化后的對象可以在網絡上進行傳輸邑彪,也可以存儲到本地瞧毙。

*

* Parcelable(android 專用):

* 除了Serializable之外,使用Parcelable也可以實現相同的效果寄症,

* 不過不同于將對象進行序列化宙彪,Parcelable方式的實現原理是將一個完整的對象進行分解,

* 而分解后的每一部分都是Intent所支持的數據類型有巧,這樣也就實現傳遞對象的功能了释漆。

要求被傳遞的對象必須實現上述2種接口中的一種才能通過Intent直接傳遞。

*/publicclassMainActivityextendsActivity{privateTextView mTvOpenNew;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){? ? ? ? ? ? ? ? Intent open =newIntent(MainActivity.this,SecondActivity.class);? ? ? ? ? ? ? ? Person person =newPerson();? ? ? ? ? ? ? ? person.setName("一去二三里");? ? ? ? ? ? ? ? person.setAge(18);// 傳輸方式一篮迎,intent直接調用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 傳輸方式二男图,intent利用putExtras(注意s)傳入bundle/**

? ? ? ? ? ? ? ? Bundle bundle = new Bundle();

? ? ? ? ? ? ? ? bundle.putSerializable("bundle_ser",person);

? ? ? ? ? ? ? ? open.putExtras(bundle);

? ? ? ? ? ? ? ? */startActivity(open);? ? ? ? ? ? }? ? ? ? });? ? }}

SecondActivity

public class Second Activity extends Activity{privateTextView mTvDate;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);?

?setContentView(R.layout.activity_second);?

?mTvDate = (TextView) findViewById(R.id.mTvDate);

?Intent intent = getIntent();// 關鍵方法:getSerializableExtra ,我們的類是實現了Serializable接口的甜橱,所以寫這個方法獲得對象// public class Person implements SerializablePerson per = (Person)intent.getSerializableExtra("put_ser_test");//Person per = (Person)intent.getSerializableExtra("bundle_ser");mTvDate.setText("名字:"+per.getName()+"\\n"+"年齡:"+per.getAge()); }}

Serializable的序列化.gif

Serializable 到此完成

三逊笆、android專用的Parcelable的序列化的例子

我們寫一個實體類,實現Parcelable接口渗鬼,馬上就被要求

1览露、復寫describeContents方法和writeToParcel方法

2、實例化靜態(tài)內部對象CREATOR譬胎,實現接口Parcelable.Creator 差牛。

也就是,隨便一個類實現了Parcelable接口就一開始就會變成這樣子

Parcelable方式的實現原理是將一個完整的對象進行分解堰乔,而分解后的每一部分都是Intent所支持的數據類型偏化,這樣也就實現傳遞對象的功能了。

publicclassPenimplementsParcelable{privateString color;privateintsize;protectedPen(Parcel in){? ? ? ? color = in.readString();? ? ? ? size = in.readInt();? ? }publicstaticfinalCreator CREATOR =newCreator() {@OverridepublicPencreateFromParcel(Parcel in){returnnewPen(in);? ? ? ? }@OverridepublicPen[] newArray(intsize) {returnnewPen[size];? ? ? ? }? ? };@OverridepublicintdescribeContents(){return0;? ? }@OverridepublicvoidwriteToParcel(Parcel dest,intflags){? ? ? ? dest.writeString(color);? ? ? ? dest.writeInt(size);? ? }}

系統(tǒng)已經幫我們做了很多事情镐侯,我們需要做的很簡單侦讨,就寫寫我們自己需要的構造方法,寫一下私有變量的get和set

大概變成這樣子:

packagecom.amqr.serializabletest.entity;importandroid.os.Parcel;importandroid.os.Parcelable;/**


*/publicclassPenimplementsParcelable{privateString color;privateintsize;// 系統(tǒng)自動添加苟翻,給createFromParcel里面用protectedPen(Parcel in){? ? ? ? color = in.readString();? ? ? ? size = in.readInt();? ? }publicstaticfinalCreator CREATOR =newCreator() {/**? ? ? ? *? ? ? ? *@paramin? ? ? ? *@return* createFromParcel()方法中我們要去讀取剛才寫出的name和age字段韵卤,? ? ? ? * 并創(chuàng)建一個Person對象進行返回,其中color和size都是調用Parcel的readXxx()方法讀取到的崇猫,? ? ? ? * 注意這里讀取的順序一定要和剛才寫出的順序完全相同沈条。? ? ? ? * 讀取的工作我們利用一個構造函數幫我們完成了? ? ? ? */@OverridepublicPencreateFromParcel(Parcel in){returnnewPen(in);// 在構造函數里面完成了 讀取 的工作}//供反序列化本類數組時調用的@OverridepublicPen[] newArray(intsize) {returnnewPen[size];? ? ? ? }? ? };@OverridepublicintdescribeContents(){return0;// 內容接口描述,默認返回0即可诅炉。}@OverridepublicvoidwriteToParcel(Parcel dest,intflags){? ? ? ? dest.writeString(color);// 寫出 colordest.writeInt(size);// 寫出 size}// ======分割線蜡歹,寫寫get和set//個人自己添加publicPen(){? ? }//個人自己添加publicPen(String color,intsize){this.color = color;this.size = size;? ? }publicStringgetColor(){returncolor;? ? }publicvoidsetColor(String color){this.color = color;? ? }publicintgetSize(){returnsize;? ? }publicvoidsetSize(intsize){this.size = size;? ? }}

其實說起來Parcelable寫起來也不是很麻煩屋厘,在as里面,我們的一個實體類寫好私有變量之后月而,讓這個類繼承自Parcelable汗洒,接下的步驟是:

1、復寫兩個方法父款,分別是describeContents和writeToParcel

2溢谤、實例化靜態(tài)內部對象CREATOR,實現接口Parcelable.Creator 憨攒。 以上這兩步系統(tǒng)都已經幫我們自動做好了

3溯香、自己寫寫我們所需要的構造方法,變量的get和set

實現自Parcelable實體Bean已經寫好了浓恶,接下來我們結合MainActivity和ThirdActivity來使用以下:


* 進行Android開發(fā)的時候玫坛,我們都知道不能將對象的引用傳給Activities或者Fragments,

* 我們需要將這些對象放到一個Intent或者Bundle里面包晰,然后再傳遞湿镀。

*

*

* Android中Intent如果要傳遞類對象,可以通過兩種方式實現伐憾。

* 方式一:Serializable勉痴,要傳遞的類實現Serializable接口傳遞對象,

* 方式二:Parcelable树肃,要傳遞的類實現Parcelable接口傳遞對象蒸矛。

*

* Serializable(Java自帶):

* Serializable是序列化的意思,表示將一個對象轉換成可存儲或可傳輸的狀態(tài)胸嘴。序列化后的對象可以在網絡上進行傳輸雏掠,也可以存儲到本地。

*

* Parcelable(android 專用):

* 除了Serializable之外劣像,使用Parcelable也可以實現相同的效果乡话,

* 不過不同于將對象進行序列化,Parcelable方式的實現原理是將一個完整的對象進行分解耳奕,

* 而分解后的每一部分都是Intent所支持的數據類型绑青,這樣也就實現傳遞對象的功能了。

要求被傳遞的對象必須實現上述2種接口中的一種才能通過Intent直接傳遞屋群。

*/publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){? ? ? ? ? ? ? ? Intent open =newIntent(MainActivity.this, SecondActivity.class);? ? ? ? ? ? ? ? Person person =newPerson();? ? ? ? ? ? ? ? person.setName("一去二三里");? ? ? ? ? ? ? ? person.setAge(18);// 傳輸方式一闸婴,intent直接調用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 傳輸方式二,intent利用putExtras(注意s)傳入bundle/**

? ? ? ? ? ? ? ? Bundle bundle = new Bundle();

? ? ? ? ? ? ? ? bundle.putSerializable("bundle_ser",person);

? ? ? ? ? ? ? ? open.putExtras(bundle);

? ? ? ? ? ? ? ? */startActivity(open);? ? ? ? ? ? }? ? ? ? });// 采用Parcelable的方式findViewById(R.id.mTvOpenThird).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){? ? ? ? ? ? ? ? Intent mTvOpenThird =newIntent(MainActivity.this,ThirdActivity.class);? ? ? ? ? ? ? ? Pen tranPen =newPen();? ? ? ? ? ? ? ? tranPen.setColor("big red");? ? ? ? ? ? ? ? tranPen.setSize(98);// public Intent putExtra(String name, Parcelable value)mTvOpenThird.putExtra("parcel_test",tranPen);? ? ? ? ? ? ? ? startActivity(mTvOpenThird);? ? ? ? ? ? }? ? ? ? });? ? }}

ThirdActivity

packagecom.amqr.serializabletest;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.TextView;importcom.amqr.serializabletest.entity.Pen;/**


*/publicclassThirdActivityextendsActivity{privateTextView mTvThirdDate;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_third);? ? ? ? mTvThirdDate = (TextView) findViewById(R.id.mTvThirdDate);//? ? ? ? Intent intent = getIntent();//? ? ? ? Pen pen = (Pen)intent.getParcelableExtra("parcel_test");Pen pen = (Pen)getIntent().getParcelableExtra("parcel_test");? ? ? ? mTvThirdDate = (TextView) findViewById(R.id.mTvThirdDate);? ? ? ? mTvThirdDate.setText("顏色:"+pen.getColor()+"\\n"+"大小:"+pen.getSize());? ? }}

Parcelable的方式.gif

完成芍躏,Serializable 和Parcelable 這兩種方式都介紹完成了邪乍。接下說一說對比

四、Serializable 和Parcelable的對比

android上應該盡量采用Parcelable,效率至上

編碼上:

Serializable代碼量少溺欧,寫起來方便

Parcelable代碼多一些

效率上:

Parcelable的速度比高十倍以上

serializable的迷人之處在于你只需要對某個類以及它的屬性實現Serializable 接口即可。Serializable 接口是一種標識接口(marker interface)柏肪,這意味著無需實現方法姐刁,Java便會對這個對象進行高效的序列化操作。

這種方法的缺點是使用了反射烦味,序列化的過程較慢聂使。這種機制會在序列化的時候創(chuàng)建許多的臨時對象,容易觸發(fā)垃圾回收谬俄。

Parcelable方式的實現原理是將一個完整的對象進行分解柏靶,而分解后的每一部分都是Intent所支持的數據類型,這樣也就實現傳遞對象的功能了

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末溃论,一起剝皮案震驚了整個濱河市屎蜓,隨后出現的幾起案子,更是在濱河造成了極大的恐慌钥勋,老刑警劉巖炬转,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異算灸,居然都是意外死亡扼劈,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門菲驴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荐吵,“玉大人,你說我怎么就攤上這事赊瞬∠燃澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵巧涧,是天一觀的道長榨婆。 經常有香客問我,道長褒侧,這世上最難降的妖魔是什么良风? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮闷供,結果婚禮上烟央,老公的妹妹穿的比我還像新娘。我一直安慰自己歪脏,他們只是感情好疑俭,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著婿失,像睡著了一般钞艇。 火紅的嫁衣襯著肌膚如雪啄寡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天哩照,我揣著相機與錄音挺物,去河邊找鬼。 笑死飘弧,一個胖子當著我的面吹牛识藤,可吹牛的內容都是我干的。 我是一名探鬼主播次伶,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼痴昧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冠王?” 一聲冷哼從身側響起赶撰,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柱彻,沒想到半個月后扣囊,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡绒疗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年侵歇,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吓蘑。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡惕虑,死狀恐怖,靈堂內的尸體忽然破棺而出磨镶,到底是詐尸還是另有隱情溃蔫,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布琳猫,位于F島的核電站伟叛,受9級特大地震影響,放射性物質發(fā)生泄漏脐嫂。R本人自食惡果不足惜统刮,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望账千。 院中可真熱鬧侥蒙,春花似錦、人聲如沸匀奏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至论衍,卻和暖如春瑞佩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遏考,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像矢沿,于是被迫代替她去往敵國和親滥搭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容