Parcelable vs Serializable

###Parcelable vs Serializableandroid

在一開始學習Android的時候,咱們就知道了不能在Activity和Fragment之間直接傳遞對象,必須使用Intent或者Bundle。 查看api後,咱們發現有兩個選擇,讓咱們的對象要麼實現Parcelable,要麼實現Serializable。做爲Java開發者,咱們都知道Serializable機制,那麼爲何還須要Parcelable呢? 要接解答這個問題,先來看兩個列子git

####Serializable-簡潔之至github

// access modifiers, accessors and constructors omitted for brevity
public class SerializableDeveloper implements Serializable
    String name;
    int yearsOfExperience;
    List<Skill> skillSet;
    float favoriteFloat;

    static class Skill implements Serializable {
        String name;
        boolean programmingRelated;
    }
}

正如你所見到的,只須要在類和成員變量引用類實現Serializable接口就能夠了,而且不須要實現任何方法。其餘的事情通通交給Java去作,簡潔之至。 可是Serializable的問題就是處理太慢,Java是採用反射去實現序列號操做。而且在處理序列化的時候還會生成大量的對象,致使GC頻繁發生。api

####Parcelable-速度之王數組

// access modifiers, accessors and regular constructors ommited for brevity
class ParcelableDeveloper implements Parcelable {
String name;
int yearsOfExperience;
List<Skill> skillSet;
float favoriteFloat;

ParcelableDeveloper(Parcel in) {
    this.name = in.readString();
    this.yearsOfExperience = in.readInt();
    this.skillSet = new ArrayList<Skill>();
    in.readTypedList(skillSet, Skill.CREATOR);
    this.favoriteFloat = in.readFloat();
}

void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeInt(yearsOfExperience);
    dest.writeTypedList(skillSet);
    dest.writeFloat(favoriteFloat);
}

int describeContents() {
    return 0;
}


static final Parcelable.Creator<ParcelableDeveloper> CREATOR
        = new Parcelable.Creator<ParcelableDeveloper>() {

    ParcelableDeveloper createFromParcel(Parcel in) {
        return new ParcelableDeveloper(in);
    }

    ParcelableDeveloper[] newArray(int size) {
        return new ParcelableDeveloper[size];
    }
};

static class Skill implements Parcelable {
    String name;
    boolean programmingRelated;

    Skill(Parcel in) {
        this.name = in.readString();
        this.programmingRelated = (in.readInt() == 1);
    }

    @Override
    void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(programmingRelated ? 1 : 0);
    }

    static final Parcelable.Creator<Skill> CREATOR
        = new Parcelable.Creator<Skill>() {

        Skill createFromParcel(Parcel in) {
            return new Skill(in);
        }

        Skill[] newArray(int size) {
            return new Skill[size];
        }
    };

    @Override
    int describeContents() {
        return 0;
    }
}
}

根據google開發人員所說,這段代碼執行速度會有明顯的提高。其中一個緣由是,咱們正在明確有關序列化過程,而不是使用反射來推斷它。這裏也能夠看到,代碼爲實現這個目的作了大量的優化。 然而Parcelable也不是免費的,它須要按規則編寫大量的代碼模板去實現序列化過程,而且難以閱讀。app

####性能測試ide

那麼問題來了,Parcelable究竟有多快?工具

#####測試步驟性能

  1. 在Activity中使用Bundle#writeToParcel(Parcel, int)方法將一個對象寫入,而後再取出來來模仿對象傳遞的過程。
  2. 重複運行1000次
  3. 取10次平均值,爲了反映不一樣內存使用,其餘app不一樣cpu消耗等狀況
  4. 使用上面的SerializableDeveloperParcelableDeveloper進行測試
  5. 在不一樣手機不行版本下運行 + LG Nexus 4 - Android 4.2.2 + Samsung Nexus 10 - Android 4.2.2 + HTC Desire Z - Android 2.3.3

#####測試結果學習

測試結果

Nexus 10 Serializable: 1.0004ms, Parcelable: 0.0850ms - 10.16x 提高. Nexus 4 Serializable: 1.8539ms - Parcelable: 0.1824ms - 11.80x 提高. Desire Z Serializable: 5.1224ms - Parcelable: 0.2938ms - 17.36x 提高.

結果就是這樣,Parcelable至少比Serializable快10倍。並且還能夠看到,即便在Nexus 10上,一個相對簡單對象作一次完整的serialize/deserialize也須要1毫秒。

####結論

若是你想作一個優秀的開發者,請儘可能使用Parcelable。由於Parcelable至少會快10倍並且佔用更少的內存。 在大多數狀況下,緩慢的Serializable也不會被特別注意到。用它也不會有多大關係,可是請記住,它是一個昂貴的操做。 若是你試着傳遞數以千計的Serializable對象數組或列表,處理整個過程可能須要花費超過一秒的時間。就會致使頁面跳轉或者橫豎屏切換呆滯。

####後記

若是你看到了這裏,我就會給你免費贈送一個大禮包! 手動寫Parcelable實在是太麻煩了,並且大部分都是複製黏貼改動。網上的工具類原理也是使用apt生成代碼,而後反射執行,對效率仍是稍稍有點影響。 幸運的是,如今AndroidStudio已經有了輔助插件——Android Parcelable Code Generator。使用這款插件能夠方便的自動生成Parcelable代碼。

安裝方法:

  1. 下載安裝包
  2. 打開IntelliJ或者Android Studio
  3. Settings -> Preferences -> Plugins -> Install plugin from disk....
  4. 選擇下載的安裝包

在win中按下alt+Insert,mac按下command+N。效果以下: 生成代碼

參考資料 http://www.developerphil.com/parcelable-vs-serializable/ https://plugins.jetbrains.com/plugin/7332?pr=androidstudio https://github.com/mcharmas/android-parcelable-intellij-plugin

相關文章
相關標籤/搜索