連載內容鎮樓:
Android 面試(一 ):說說 Android 的四種啓動模式
Android 面試(二): 如何理解 Activity 的生命週期
Android 面試(三): 用廣播 BroadcastReceiver 更新 UI 界面真的好嗎?
Android 面試(四):Android Service 你真的能應答自如了嗎?
Android 面試(五):探索 Android 的 Handler
Android 面試(六):你已經用 SharedPrefrence 的 apply() 替換 commit() 了嗎?java
距離上一篇文章彷佛又是好久了,看起來也沒有不少反饋,催更就更不用說了。哈哈,放棄了。android
話說最近公司在招聘一批至少 5 年開發經驗的 Android 開發工程師,我也是忙開了花,激動得不行呀。雖然說我面試過的技術開發至少 50 人以上,但這仍是第一次開始面試 Android,此時猶如大姑娘上轎,還真是頭一回呀!git
因此很是很是很是用心地準備了良久,而後滿懷激動地開始了個人 Android 面試官角色。程序員
無奈,面試後的感受,均是開發效率聽起來很牛逼,第三方 API 用起來很是順手,但問到基礎,就拿我面試系列的題去問,沒一個答得上的,甚至是循循善誘,都無法好好回答。github
Android 開發中對兩個 Activity 以前傳遞數據,應該很熟悉吧?面試
嗯,固然沒問題。通常採用 Intent.putXXX()
就能夠實現各類輕量級數據的傳遞。微信
那對於自定義的 Object 呢?app
直接使用 Bundle
的 putSerializable()
便可。須要把對象實現 Serializable
接口,最後使用 Intent.putExtras(Bundle)
把數據放進 Intent
便可。ide
除了這種方式,還有其它方式嗎?和這種方式有什麼區別呢?測試
我知道還有 Bundle.putParcelable()
,不過咱們平時基本都只用 Serializable
方式。
爲何不用
Parcelable
方式呢?它們有什麼不一樣呢?
由於簡單呀,Serializable
方式只須要實現接口一句代碼就行了,Parcelable
我記得有不少代碼。對於它們的區別嘛,em......額......嗯.......
上面的場景,實際上就是在我近期發生的。做爲一個簡歷上 09 年入行的大齡 Android 程序員,我很是確定他的開發能力和解決問題的能力,在這方面確定甩我不少條街,不過至少在我問的問題上讓我有點大跌眼鏡,問到自定義 View 的繪製順序,直接回答不知道。問到 LaunchMode,支支吾吾,不清楚。實際上不禁得讓咱們思考,究竟是怎麼了,難道如今對於這麼多的程序猿,寫出符合需求的代碼就變得這麼重要了麼?還好,當下還有不少堅持在一線,努力把基礎帶給你們的大神,好比,扔物線朱凱,還有很是很是多的夥伴們。
大多數人可能都知道,Serializable
和 Parcelable
方式最大的區別是效率上的差別,並且對於小數據,其實差別並非很大,這些差異其實用戶層面是並不容易發現的。但這並不表明着,咱們的開發就能夠忽視這幾十毫秒甚至是幾毫秒的差距。
能夠確定的是,二者都是支持序列化和反序列化的操做。
二者最大的區別在於 存儲媒介的不一樣,Serializable
使用 I/O 讀寫存儲在硬盤上,而 Parcelable
是直接 在內存中讀寫。很明顯,內存的讀寫速度一般大於 IO 讀寫,因此在 Android 中傳遞數據優先選擇 Parcelable
。
Serializable
會使用反射,序列化和反序列化過程須要大量 I/O 操做, Parcelable
自已實現封送和解封(marshalled &unmarshalled)操做不須要用反射,數據也存放在 Native 內存中,效率要快不少。
有人直接比較過兩個的效率差異
咱們能夠來看看分別怎麼寫?
public class TestSerializable implements Serializable {
String msg;
List<ItemBean> datas;
public static class ItemBean implements Serializable{
String name;
}
}
複製代碼
public class TestParcelable implements Parcelable {
String msg;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.msg);
}
TestParcelable(String msg) {
this.msg = msg;
}
private TestParcelable(Parcel in) {
this.msg = in.readString();
}
public static final Creator<TestParcelable> CREATOR = new Creator<TestParcelable>() {
@Override
public TestParcelable createFromParcel(Parcel source) {
return new TestParcelable(source);
}
@Override
public TestParcelable[] newArray(int size) {
return new TestParcelable[size];
}
};
}
複製代碼
很明顯,Parcelable
實現起來並不容易,它有成噸的模板代碼,這使得對象變得難以閱讀和維護。但若是你真的想成爲一個優秀的 Android 開發工程師,你可能就得多在 Parcelable
上花點時間了。實在想偷懶也沒事,由於有人在 GitHub 上已經上傳了 Android Studio 的插件,幫助你自動生成這一堆模板。
對象的大小,對象的大小,對象的大小!!!
重要的事情說三遍,必定要注意對象的大小。Intent
中的 Bundle
是使用 Binder
機制進行數據傳送的。能使用的 Binder 的緩衝區是有大小限制的(有些手機是 2 M),而一個進程默認有 16 個 Binder
線程,因此一個線程能佔用的緩衝區就更小了( 有人之前作過測試,大約一個線程能夠佔用 128 KB)。因此當你看到 The Binder transaction failed because it was too large
這類 TransactionTooLargeException
異常時,你應該知道怎麼解決了。