Serializable 都這麼牛逼了,Parcelable,我還要你何用?

連載內容鎮樓:
Android 面試(一 ):說說 Android 的四種啓動模式
Android 面試(二): 如何理解 Activity 的生命週期
Android 面試(三): 用廣播 BroadcastReceiver 更新 UI 界面真的好嗎?
Android 面試(四):Android Service 你真的能應答自如了嗎?
Android 面試(五):探索 Android 的 Handler
Android 面試(六):你已經用 SharedPrefrence 的 apply() 替換 commit() 了嗎?java

一些閒聊

距離上一篇文章彷佛又是好久了,看起來也沒有不少反饋,催更就更不用說了。哈哈,放棄了。android

nanchen

話說最近公司在招聘一批至少 5 年開發經驗的 Android 開發工程師,我也是忙開了花,激動得不行呀。雖然說我面試過的技術開發至少 50 人以上,但這仍是第一次開始面試 Android,此時猶如大姑娘上轎,還真是頭一回呀!git

因此很是很是很是用心地準備了良久,而後滿懷激動地開始了個人 Android 面試官角色。程序員

無奈,面試後的感受,均是開發效率聽起來很牛逼,第三方 API 用起來很是順手,但問到基礎,就拿我面試系列的題去問,沒一個答得上的,甚至是循循善誘,都無法好好回答。github

nanchen

面試場景

Android 開發中對兩個 Activity 以前傳遞數據,應該很熟悉吧?面試

嗯,固然沒問題。通常採用 Intent.putXXX() 就能夠實現各類輕量級數據的傳遞。微信

那對於自定義的 Object 呢?app

直接使用 BundleputSerializable() 便可。須要把對象實現 Serializable 接口,最後使用 Intent.putExtras(Bundle) 把數據放進 Intent 便可。ide

除了這種方式,還有其它方式嗎?和這種方式有什麼區別呢?測試

我知道還有 Bundle.putParcelable() ,不過咱們平時基本都只用 Serializable 方式。

爲何不用 Parcelable 方式呢?它們有什麼不一樣呢?

由於簡單呀,Serializable 方式只須要實現接口一句代碼就行了,Parcelable 我記得有不少代碼。對於它們的區別嘛,em......額......嗯.......

正文

上面的場景,實際上就是在我近期發生的。做爲一個簡歷上 09 年入行的大齡 Android 程序員,我很是確定他的開發能力和解決問題的能力,在這方面確定甩我不少條街,不過至少在我問的問題上讓我有點大跌眼鏡,問到自定義 View 的繪製順序,直接回答不知道。問到 LaunchMode,支支吾吾,不清楚。實際上不禁得讓咱們思考,究竟是怎麼了,難道如今對於這麼多的程序猿,寫出符合需求的代碼就變得這麼重要了麼?還好,當下還有不少堅持在一線,努力把基礎帶給你們的大神,好比,扔物線朱凱,還有很是很是多的夥伴們。

大多數人可能都知道,SerializableParcelable 方式最大的區別是效率上的差別,並且對於小數據,其實差別並非很大,這些差異其實用戶層面是並不容易發現的。但這並不表明着,咱們的開發就能夠忽視這幾十毫秒甚至是幾毫秒的差距。

Serializable 和 Parcelable 的區別

能夠確定的是,二者都是支持序列化和反序列化的操做。

二者最大的區別在於 存儲媒介的不一樣Serializable 使用 I/O 讀寫存儲在硬盤上,而 Parcelable 是直接 在內存中讀寫。很明顯,內存的讀寫速度一般大於 IO 讀寫,因此在 Android 中傳遞數據優先選擇 Parcelable

Serializable 會使用反射,序列化和反序列化過程須要大量 I/O 操做, Parcelable 自已實現封送和解封(marshalled &unmarshalled)操做不須要用反射,數據也存放在 Native 內存中,效率要快不少。

有人直接比較過兩個的效率差異

nanchen

咱們能夠來看看分別怎麼寫?

  • Serializable 「簡單易用」一直都是它的代名詞
public class TestSerializable implements Serializable {
    String msg;
    
    List<ItemBean> datas;
    
    public static class ItemBean implements Serializable{
        String name;
    }
}
複製代碼
  • Parcelable 速度至上
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 的插件,幫助你自動生成這一堆模板。

地址:github.com/mcharmas/an…

在兩個 Activity 之間傳遞對象還須要注意什麼呢?

對象的大小,對象的大小,對象的大小!!!

重要的事情說三遍,必定要注意對象的大小。Intent 中的 Bundle 是使用 Binder 機制進行數據傳送的。能使用的 Binder 的緩衝區是有大小限制的(有些手機是 2 M),而一個進程默認有 16 個 Binder 線程,因此一個線程能佔用的緩衝區就更小了( 有人之前作過測試,大約一個線程能夠佔用 128 KB)。因此當你看到 The Binder transaction failed because it was too large 這類 TransactionTooLargeException 異常時,你應該知道怎麼解決了。

作不完的開源,寫不完的矯情。歡迎掃描下方二維碼或者公衆號搜索「nanchen」關注個人微信公衆號,目前多運營 Android ,盡本身所能爲你提高。若是你喜歡,爲我點贊分享吧~
nanchen
相關文章
相關標籤/搜索