Android序列化總結(jié)

段子

公園里,一位仙風(fēng)鶴骨的老者在打太極泣洞,一招一式都仙氣十足忧风,一個(gè)年輕人走過(guò)去:“大爺,太極這玩意兒花拳繡腿球凰,你練它干啥狮腿?”老者淡淡一笑:“年輕人,你還沒(méi)有領(lǐng)悟到太極的真諦呕诉,這樣蚤霞,你用最大力氣打我試試∫宥ぃ”于是年輕人用力打了老頭一拳,被訛了八萬(wàn)六规肴。

前言

序列化使用很簡(jiǎn)單捶闸,但是其中的一些細(xì)節(jié)并不是所有人都清楚。在日常的應(yīng)用開(kāi)發(fā)中拖刃,我們可能需要讓某些對(duì)象離開(kāi)內(nèi)存空間删壮,存儲(chǔ)到物理磁盤,以便長(zhǎng)期保存兑牡,同時(shí)也能減少對(duì)內(nèi)存的壓力央碟,而在需要時(shí)再將其從磁盤讀取到內(nèi)存,比如將某個(gè)特定的對(duì)象保存到文件中均函,隔一段時(shí)間后再把它讀取到內(nèi)存中使用亿虽,那么該對(duì)象就需要實(shí)現(xiàn)序列化操作,在java中可以使用Serializable接口實(shí)現(xiàn)對(duì)象的序列化洛勉,而在android中既可以使用Serializable接口實(shí)現(xiàn)對(duì)象序列化也可以使用Parcelable接口實(shí)現(xiàn)對(duì)象序列化粘秆,但是在內(nèi)存操作時(shí)更傾向于實(shí)現(xiàn)Parcelable接口,這樣會(huì)使用傳輸效率更高效收毫。接下來(lái)我們將分別詳細(xì)地介紹這樣兩種序列化操作攻走。

序列化與反序列

首先來(lái)了解一下序列化與反序列化。

(1)序列化

由于存在于內(nèi)存中的對(duì)象都是暫時(shí)的此再,無(wú)法長(zhǎng)期駐存昔搂,為了把對(duì)象的狀態(tài)保持下來(lái),這時(shí)需要把對(duì)象寫入到磁盤或者其他介質(zhì)中输拇,這個(gè)過(guò)程就叫做序列化摘符。

(2)反序列化

反序列化恰恰是序列化的反向操作,也就是說(shuō)淳附,把已存在在磁盤或者其他介質(zhì)中的對(duì)象议慰,反序列化(讀取)到內(nèi)存中奴曙,以便后續(xù)操作别凹,而這個(gè)過(guò)程就叫做反序列化。

概括性來(lái)說(shuō)序列化是指將對(duì)象實(shí)例的狀態(tài)存儲(chǔ)到存儲(chǔ)媒體(磁盤或者其他介質(zhì))的過(guò)程洽糟。在此過(guò)程中炉菲,先將對(duì)象的公共字段和私有字段以及類的名稱(包括類所在的程序集)轉(zhuǎn)換為字節(jié)流,然后再把字節(jié)流寫入數(shù)據(jù)流坤溃。在隨后對(duì)對(duì)象進(jìn)行反序列化時(shí)拍霜,將創(chuàng)建出與原對(duì)象完全相同的副本。

(3)實(shí)現(xiàn)序列化的必要條件

一個(gè)對(duì)象要實(shí)現(xiàn)序列化操作薪介,該類就必須實(shí)現(xiàn)了Serializable接口或者Parcelable接口祠饺,其中Serializable接口是在java中的序列化抽象類,而Parcelable接口則是android中特有的序列化接口汁政,在某些情況下道偷,Parcelable接口實(shí)現(xiàn)的序列化更為高效,關(guān)于它們的實(shí)現(xiàn)案例我們后續(xù)會(huì)分析记劈,這里只要清楚知道實(shí)現(xiàn)序列化操作時(shí)必須實(shí)現(xiàn)Serializable接口或者Parcelable接口之一即可勺鸦。

(4)序列化的應(yīng)用情景

主要有以下情況(但不限于以下情況)
1)內(nèi)存中的對(duì)象寫入到硬盤;
2)用套接字在網(wǎng)絡(luò)上傳送對(duì)象目木;

Serializable

Serializable是java提供的一個(gè)序列化接口换途,它是一個(gè)空接口,專門為對(duì)象提供標(biāo)準(zhǔn)的序列化和反序列化操作,使用Serializable實(shí)現(xiàn)類的序列化比較簡(jiǎn)單军拟,只要在類聲明中實(shí)現(xiàn)Serializable接口即可剃执,同時(shí)強(qiáng)烈建議聲明序列化標(biāo)識(shí)。如下:

public class User implements Serializable {

    private static final long serialVersionUID = -2083503801443301445L;

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

如上述代碼所示吻谋,User類實(shí)現(xiàn)的Serializable接口并聲明了序列化標(biāo)識(shí)serialVersionUID忠蝗,該ID由編輯器生成,當(dāng)然也可以自定義漓拾,如1L阁最,5L,不過(guò)還是建議使用編輯器生成唯一標(biāo)識(shí)符骇两。那么serialVersionUID有什么作用呢速种?實(shí)際上我們不聲明serialVersionUID也是可以的,因?yàn)樵谛蛄谢^(guò)程中會(huì)自動(dòng)生成一個(gè)serialVersionUID來(lái)標(biāo)識(shí)序列化對(duì)象低千。既然如此配阵,那我們還需不需要要指定呢?原因是serialVersionUID是用來(lái)輔助序列化和反序列化過(guò)程的示血,原則上序列化后的對(duì)象中serialVersionUID只有和當(dāng)前類的serialVersionUID相同才能夠正常被反序列化棋傍,也就是說(shuō)序列化與反序列化的serialVersionUID必須相同才能夠使序列化操作成功。具體過(guò)程是這樣的:序列化操作的時(shí)候系統(tǒng)會(huì)把當(dāng)前類的serialVersionUID寫入到序列化文件中难审,當(dāng)反序列化時(shí)系統(tǒng)會(huì)去檢測(cè)文件中的serialVersionUID瘫拣,判斷它是否與當(dāng)前類的serialVersionUID一致,如果一致就說(shuō)明序列化類的版本與當(dāng)前類版本是一樣的告喊,可以反序列化成功麸拄,否則失敗。報(bào)出如下UID錯(cuò)誤:

Exception in thread "main" java.io.InvalidClassException: com.zejian.test.Client; 
local class incompatible: stream classdesc serialVersionUID = -2083503801443301445, 
local class serialVersionUID = -4083503801443301445

因此強(qiáng)烈建議指定serialVersionUID黔姜,這樣的話即使微小的變化也不會(huì)導(dǎo)致crash的出現(xiàn)拢切,如果不指定的話只要這個(gè)文件多一個(gè)空格,系統(tǒng)自動(dòng)生成的UID就會(huì)截然不同的秆吵,反序列化也就會(huì)失敗淮椰。ok~,了解這么多纳寂,下面來(lái)看一個(gè)如何進(jìn)行對(duì)象序列化和反序列化的列子:

public class Demo {

    public static void main(String[] args) throws Exception {

        // 構(gòu)造對(duì)象
        User user = new User();
        user.setId(1000);
        user.setName("韓梅梅");

        // 把對(duì)象序列化到文件
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/serializable/user.txt"));
        oos.writeObject(user);
        oos.close();

        // 反序列化到內(nèi)存
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/serializable/user.txt"));
        User userBack = (User) ois.readObject();
        System.out.println("read serializable user:id=" + userBack.getId() + ", name=" + userBack.getName());
        ois.close();
    }
}

輸出結(jié)果:

read serializable user:id=1000, name=韓梅梅

從代碼可以看出只需要ObjectOutputStream和ObjectInputStream就可以實(shí)現(xiàn)對(duì)象的序列化和反序列化操作实苞,通過(guò)流對(duì)象把user對(duì)象寫到文件中,并在需要時(shí)恢復(fù)userBack對(duì)象烈疚,但是兩者并不是同一個(gè)對(duì)象了,反序列化后的對(duì)象是新創(chuàng)建的聪轿。這里有兩點(diǎn)特別注意的是如果反序列類的成員變量的類型或者類名爷肝,發(fā)生了變化,那么即使serialVersionUID相同也無(wú)法正常反序列化成功。其次是靜態(tài)成員變量屬于類不屬于對(duì)象灯抛,不會(huì)參與序列化過(guò)程金赦,使用transient關(guān)鍵字標(biāo)記的成員變量也不參與序列化過(guò)程。

另外对嚼,系統(tǒng)的默認(rèn)序列化過(guò)程是可以改變的夹抗,通過(guò)實(shí)現(xiàn)如下4個(gè)方法,即可以控制系統(tǒng)的默認(rèn)序列化和反序列過(guò)程:

public class User implements Serializable {

    private static final long serialVersionUID = -4083503801443301445L;

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    /**
     * 序列化時(shí),
     * 首先系統(tǒng)會(huì)先調(diào)用writeReplace方法,在這個(gè)階段,
     * 可以進(jìn)行自己操作,將需要進(jìn)行序列化的對(duì)象換成我們指定的對(duì)象.
     * 一般很少重寫該方法
     */
    private Object writeReplace() throws ObjectStreamException {
        System.out.println("writeReplace invoked");
        return this;
    }
    /**
     *接著系統(tǒng)將調(diào)用writeObject方法,
     * 來(lái)將對(duì)象中的屬性一個(gè)個(gè)進(jìn)行序列化,
     * 我們可以在這個(gè)方法中控制住哪些屬性需要序列化.
     * 這里只序列化name屬性
     */
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
        System.out.println("writeObject invoked");
        out.writeObject(this.name == null ? "默認(rèn)值" : this.name);
    }

    /**
     * 反序列化時(shí),系統(tǒng)會(huì)調(diào)用readObject方法,將我們剛剛在writeObject方法序列化好的屬性,
     * 反序列化回來(lái).然后通過(guò)readResolve方法,我們也可以指定系統(tǒng)返回給我們特定的對(duì)象
     * 可以不是writeReplace序列化時(shí)的對(duì)象,可以指定其他對(duì)象.
     */
    private void readObject(java.io.ObjectInputStream in) throws IOException,
            ClassNotFoundException {
        System.out.println("readObject invoked");
        this.name = (String) in.readObject();
        System.out.println("got name:" + name);
    }


    /**
     * 通過(guò)readResolve方法,我們也可以指定系統(tǒng)返回給我們特定的對(duì)象
     * 可以不是writeReplace序列化時(shí)的對(duì)象,可以指定其他對(duì)象.
     * 一般很少重寫該方法
     */
    private Object readResolve() throws ObjectStreamException {
        System.out.println("readResolve invoked");
        return this;
    }
}

通過(guò)上面的4個(gè)方法纵竖,我們就可以隨意控制序列化的過(guò)程了漠烧,由于在大部分情況下我們都沒(méi)必要重寫這4個(gè)方法,因此這里我們也不過(guò)介紹了靡砌,只要知道有這么一回事就行已脓。ok~,對(duì)于Serializable的介紹就先到這里通殃。

Parcelable

鑒于Serializable在內(nèi)存序列化上開(kāi)銷比較大度液,而內(nèi)存資源屬于android系統(tǒng)中的稀有資源(android系統(tǒng)分配給每個(gè)應(yīng)用的內(nèi)存開(kāi)銷都是有限的),為此android中提供了Parcelable接口來(lái)實(shí)現(xiàn)序列化操作画舌,Parcelable的性能比Serializable好堕担,在內(nèi)存開(kāi)銷方面較小,所以在內(nèi)存間數(shù)據(jù)傳輸時(shí)推薦使用Parcelable曲聂,如通過(guò)Intent在activity間傳輸數(shù)據(jù)霹购,而Parcelable的缺點(diǎn)就使用起來(lái)比較麻煩,下面給出一個(gè)Parcelable接口的實(shí)現(xiàn)案例句葵,大家感受一下:

public class User implements Parcelable {

    public int id;
    public String name;
    public User friend;

    /**
     * 當(dāng)前對(duì)象的內(nèi)容描述,一般返回0即可
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 將當(dāng)前對(duì)象寫入序列化結(jié)構(gòu)中
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeString(this.name);
        dest.writeParcelable(this.friend, 0);
    }

    public NewClient() {}

    /**
     * 從序列化后的對(duì)象中創(chuàng)建原始對(duì)象
     */
    protected NewClient(Parcel in) {
        this.id = in.readInt();
        this.name = in.readString();
       //friend是另一個(gè)序列化對(duì)象厕鹃,此方法序列需要傳遞當(dāng)前線程的上下文類加載器,否則會(huì)報(bào)無(wú)法找到類的錯(cuò)誤
       this.friend=in.readParcelable(Thread.currentThread().getContextClassLoader());
    }

    /**
     * public static final一個(gè)都不能少乍丈,內(nèi)部對(duì)象CREATOR的名稱也不能改變剂碴,必須全部大寫。
     * 重寫接口中的兩個(gè)方法:
     * createFromParcel(Parcel in) 實(shí)現(xiàn)從Parcel容器中讀取傳遞數(shù)據(jù)值,封裝成Parcelable對(duì)象返回邏輯層轻专,
     * newArray(int size) 創(chuàng)建一個(gè)類型為T忆矛,長(zhǎng)度為size的數(shù)組,供外部類反序列化本類數(shù)組使用请垛。
     */
    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        /**
         * 從序列化后的對(duì)象中創(chuàng)建原始對(duì)象
         */
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        /**
         * 創(chuàng)建指定長(zhǎng)度的原始對(duì)象數(shù)組
         */
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

從代碼可知催训,在序列化的過(guò)程中需要實(shí)現(xiàn)的功能有序列化和反序列以及內(nèi)容描述。其中writeToParcel方法實(shí)現(xiàn)序列化功能宗收,其內(nèi)部是通過(guò)Parcel的一系列write方法來(lái)完成的漫拭,接著通過(guò)CREATOR內(nèi)部對(duì)象來(lái)實(shí)現(xiàn)反序列化,其內(nèi)部通過(guò)createFromParcel方法來(lái)創(chuàng)建序列化對(duì)象并通過(guò)newArray方法創(chuàng)建數(shù)組混稽,最終利用Parcel的一系列read方法完成反序列化采驻,最后由describeContents完成內(nèi)容描述功能审胚,該方法一般返回0,僅當(dāng)對(duì)象中存在文件描述符時(shí)返回1礼旅。同時(shí)由于User是另一個(gè)序列化對(duì)象膳叨,因此在反序列化方法中需要傳遞當(dāng)前線程的上下文類加載器,否則會(huì)報(bào)無(wú)法找到類的錯(cuò)誤痘系。
??
簡(jiǎn)單用一句話概括來(lái)說(shuō)就是通過(guò)writeToParcel將我們的對(duì)象映射成Parcel對(duì)象菲嘴,再通過(guò)createFromParcel將Parcel對(duì)象映射成我們的對(duì)象。也可以將Parcel看成是一個(gè)類似Serliazable的讀寫流汰翠,通過(guò)writeToParcel把對(duì)象寫到流里面龄坪,在通過(guò)createFromParcel從流里讀取對(duì)象,這個(gè)過(guò)程需要我們自己來(lái)實(shí)現(xiàn)并且寫的順序和讀的順序必須一致奴璃。ok~悉默,到此Parcelable接口的序列化實(shí)現(xiàn)基本介紹完。
??
那么在哪里會(huì)使用到Parcelable對(duì)象呢苟穆?其實(shí)通過(guò)Intent傳遞復(fù)雜類型(如自定義引用類型數(shù)據(jù))的數(shù)據(jù)時(shí)就需要使用Parcelable對(duì)象抄课,如下是日常應(yīng)用中Intent關(guān)于Parcelable對(duì)象的一些操作方法,引用類型必須實(shí)現(xiàn)Parcelable接口才能通過(guò)Intent傳遞雳旅,而基本數(shù)據(jù)類型跟磨,String類型則可直接通過(guò)Intent傳遞而且Intent本身也實(shí)現(xiàn)了Parcelable接口,所以可以輕松地在組件間進(jìn)行傳輸攒盈。

方法名稱 含義
putExtra(String name, Parcelable value) 設(shè)置自定義類型并實(shí)現(xiàn)Parcelable的對(duì)象
putExtra(String name, Parcelable[] value) 設(shè)置自定義類型并實(shí)現(xiàn)Parcelable的對(duì)象數(shù)組
putParcelableArrayListExtra(String name, ArrayList value) 設(shè)置List數(shù)組抵拘,其元素必須是實(shí)現(xiàn)了Parcelable接口的數(shù)據(jù)

除了以上的Intent外系統(tǒng)還為我們提供了其他實(shí)現(xiàn)Parcelable接口的類,再如Bundle型豁、Bitmap僵蛛,它們都是可以直接序列化的,因此我們可以方便地使用它們?cè)诮M件間進(jìn)行數(shù)據(jù)傳遞迎变,當(dāng)然Bundle本身也是一個(gè)類似鍵值對(duì)的容器充尉,也可存儲(chǔ)Parcelable實(shí)現(xiàn)類,其API方法跟Intent基本相似衣形,由于這些屬于android基礎(chǔ)知識(shí)點(diǎn)驼侠,這里我們就不過(guò)多介紹了。

Parcelable 與 Serializable 區(qū)別

(1)兩者的實(shí)現(xiàn)差異

Serializable的實(shí)現(xiàn)谆吴,只需要實(shí)現(xiàn)Serializable接口即可倒源。這只是給對(duì)象打了一個(gè)標(biāo)記(UID),系統(tǒng)會(huì)自動(dòng)將其序列化句狼。而Parcelabel的實(shí)現(xiàn)笋熬,不僅需要實(shí)現(xiàn)Parcelabel接口,還需要在類中添加一個(gè)靜態(tài)成員變量CREATOR腻菇,這個(gè)變量需要實(shí)現(xiàn) Parcelable.Creator 接口突诬,并實(shí)現(xiàn)讀寫的抽象方法苫拍。

(2)兩者的設(shè)計(jì)初衷

Serializable的設(shè)計(jì)初衷是為了序列化對(duì)象到本地文件、數(shù)據(jù)庫(kù)旺隙、網(wǎng)絡(luò)流、RMI以便數(shù)據(jù)傳輸骏令,當(dāng)然這種傳輸可以是程序內(nèi)的也可以是兩個(gè)程序間的蔬捷。而Android的Parcelable的設(shè)計(jì)初衷是由于Serializable效率過(guò)低,消耗大榔袋,而android中數(shù)據(jù)傳遞主要是在內(nèi)存環(huán)境中(內(nèi)存屬于android中的稀有資源)周拐,因此Parcelable的出現(xiàn)為了滿足數(shù)據(jù)在內(nèi)存中低開(kāi)銷而且高效地傳遞問(wèn)題。

(3)兩者效率選擇

Serializable使用IO讀寫存儲(chǔ)在硬盤上凰兑。序列化過(guò)程使用了反射技術(shù)妥粟,并且期間產(chǎn)生臨時(shí)對(duì)象,優(yōu)點(diǎn)代碼少吏够,在將對(duì)象序列化到存儲(chǔ)設(shè)置中或?qū)?duì)象序列化后通過(guò)網(wǎng)絡(luò)傳輸時(shí)建議選擇Serializable勾给。
Parcelable是直接在內(nèi)存中讀寫,我們知道內(nèi)存的讀寫速度肯定優(yōu)于硬盤讀寫速度锅知,所以Parcelable序列化方式性能上要優(yōu)于Serializable方式很多播急。所以Android應(yīng)用程序在內(nèi)存間數(shù)據(jù)傳輸時(shí)推薦使用Parcelable,如activity間傳輸數(shù)據(jù)和AIDL數(shù)據(jù)傳遞售睹。大多數(shù)情況下使用Serializable也是沒(méi)什么問(wèn)題的桩警,但是針對(duì)Android應(yīng)用程序在內(nèi)存間數(shù)據(jù)傳輸還是建議大家使用Parcelable方式實(shí)現(xiàn)序列化,畢竟性能好很多昌妹,其實(shí)也沒(méi)多麻煩捶枢。
Parcelable也不是不可以在網(wǎng)絡(luò)中傳輸,只不過(guò)實(shí)現(xiàn)和操作過(guò)程過(guò)于麻煩并且為了防止android版本不同而導(dǎo)致Parcelable可能不同的情況飞崖,因此在序列化到存儲(chǔ)設(shè)備或者網(wǎng)絡(luò)傳輸方面還是盡量選擇Serializable接口烂叔。

AndroidStudio中的快捷生成方式

(1)AndroidStudio快捷生成Parcelable代碼

在程序開(kāi)發(fā)過(guò)程中,我們實(shí)現(xiàn)Parcelable接口的代碼都是類似的蚜厉,如果我們每次實(shí)現(xiàn)一個(gè)Parcelable接口類长已,就得去編寫一次重復(fù)的代碼,這顯然是不可取的昼牛,不過(guò)幸運(yùn)的是术瓮,android studio 提供了自動(dòng)實(shí)現(xiàn)Parcelable接口的方法的插件,相當(dāng)實(shí)現(xiàn)贰健,我們只需要打開(kāi)Setting胞四,找到plugin插件,然后搜索Parcelable插件伶椿,最后找到android Parcelable code generator 安裝即可:

重啟android studio后辜伟,我們創(chuàng)建一個(gè)User類氓侧,如下:

public class User {

    public int id;

    public int age;

    public String name;
}

然后使用剛剛安裝的插件協(xié)助我們生成實(shí)現(xiàn)Parcelable接口的代碼,window快捷鍵:Alt+Insert导狡,Mac快捷鍵:cmd+n约巷,如下:

最后結(jié)果如下:

public class User implements Parcelable {

    public int id;

    public int age;

    public String name;

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.id);
        dest.writeInt(this.age);
        dest.writeString(this.name);
    }

    public User() {
    }

    protected User(Parcel in) {
        this.id = in.readInt();
        this.age = in.readInt();
        this.name = in.readString();
    }

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

(2)AndroidStudio快捷生成Serializable的UID

在正常情況下,AS是默認(rèn)關(guān)閉serialVersionUID生成提示的旱捧,我們需要打開(kāi)setting独郎,找到檢測(cè)(Inspections選項(xiàng)),開(kāi)啟 Serializable class without serialVersionUID 檢測(cè)即可枚赡,如下:

然后新建User類實(shí)現(xiàn)Serializable接口氓癌,右側(cè)會(huì)提示添加serialVersionUID,如下:

鼠標(biāo)放在類名上贫橙,Alt+Enter(Mac:cmd+Enter)贪婉,快捷代碼提示,生成serialVersionUID即可:

最終生成結(jié)果:

public class User implements Serializable {

    private static final long serialVersionUID = 6748592377066215128L;
    
    public int id;

    public int age;

    public String name;
}

總結(jié)

以上就是Android序列化的全部?jī)?nèi)容卢肃,很簡(jiǎn)單疲迂,但是也有細(xì)節(jié)。我有一個(gè)想法践剂,就是后面專門寫一些表面很簡(jiǎn)單但是細(xì)節(jié)可能不清楚的知識(shí)點(diǎn)鬼譬,我們不要始終把目光聚集在大框架上、高端前沿技術(shù)什么的逊脯,偶爾研究研究基礎(chǔ)的東西也不錯(cuò)优质。

我的博客即將搬運(yùn)同步至騰訊云+社區(qū),邀請(qǐng)大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=1i1t9pd69ux2t

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末军洼,一起剝皮案震驚了整個(gè)濱河市巩螃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匕争,老刑警劉巖避乏,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異甘桑,居然都是意外死亡拍皮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門跑杭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)铆帽,“玉大人,你說(shuō)我怎么就攤上這事德谅〉鳎” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵窄做,是天一觀的道長(zhǎng)愧驱。 經(jīng)常有香客問(wèn)我慰技,道長(zhǎng),這世上最難降的妖魔是什么组砚? 我笑而不...
    開(kāi)封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任吻商,我火速辦了婚禮,結(jié)果婚禮上糟红,老公的妹妹穿的比我還像新娘手报。我一直安慰自己,他們只是感情好改化,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著枉昏,像睡著了一般陈肛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兄裂,一...
    開(kāi)封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天句旱,我揣著相機(jī)與錄音,去河邊找鬼晰奖。 笑死谈撒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的匾南。 我是一名探鬼主播啃匿,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蛆楞!你這毒婦竟也來(lái)了溯乒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤豹爹,失蹤者是張志新(化名)和其女友劉穎裆悄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體臂聋,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡光稼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了孩等。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艾君。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖瞎访,靈堂內(nèi)的尸體忽然破棺而出腻贰,到底是詐尸還是另有隱情,我是刑警寧澤扒秸,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布播演,位于F島的核電站冀瓦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏写烤。R本人自食惡果不足惜翼闽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望洲炊。 院中可真熱鬧感局,春花似錦、人聲如沸暂衡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狂巢。三九已至撑毛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間唧领,已是汗流浹背藻雌。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留斩个,地道東北人胯杭。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像受啥,于是被迫代替她去往敵國(guó)和親做个。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容