組件化方案調(diào)研

組件化方案調(diào)研

組件化概念

組件化就是將一個(gè)app分成多個(gè)Module鼓鲁,如下圖钟哥,每個(gè)Module都是一個(gè)組件(也可以是一個(gè)基礎(chǔ)庫(kù)供組件依賴(lài))满葛,開(kāi)發(fā)的過(guò)程中我們可以單獨(dú)調(diào)試部分組件,組件間不需要互相依賴(lài)芬位,但可以相互調(diào)用龙巨,最終發(fā)布的時(shí)候所有組件以lib的形式被主app工程依賴(lài)并打包成一個(gè)apk额获。

1.png

模塊化、插件化和組件化的關(guān)系

對(duì)于這三者的關(guān)系:有不同的說(shuō)法恭应。
截取一些,以供參考耘眨,其實(shí)雖然每個(gè)人都有每個(gè)的不通過(guò)的理解和說(shuō)法昼榛,但是內(nèi)涵其實(shí)是一樣的。

模塊化與組件化

  1. 得到(張明慶)

    在技術(shù)開(kāi)發(fā)領(lǐng)域剔难,模塊化是指分拆代碼胆屿,即當(dāng)我們的代碼特別臃腫的時(shí)候,用模塊化將代碼分而治之偶宫、解耦分層非迹。具體到 android 領(lǐng)域,模塊化的具體實(shí)施方法分為插件化和組件化纯趋。

  2. 《 Java 應(yīng)用架構(gòu)設(shè)計(jì):模塊化模式與 OSGi 》一書(shū)中對(duì)它的定義是:模塊化是一種處理復(fù)雜系統(tǒng)分解為更好的可管理模塊的方式憎兽。

  3. 《安居客》(張磊)組件和模塊做個(gè)區(qū)別定義

    • 組件:指的是單一的功能組件,如地圖組件(MapSDK)吵冒、支付組件(AnjukePay)纯命、路由組件(Router)等等;
    • 模塊:指的是獨(dú)立的業(yè)務(wù)模塊痹栖,如新房模塊(NewHouseModule)亿汞、二手房模塊(SecondHouseModule)、即時(shí)通訊模塊(InstantMessagingModule)等等揪阿;模塊相對(duì)于組件來(lái)說(shuō)粒度更大疗我。

綜上所述咆畏,模塊化與組件化都是對(duì)于一個(gè)整體功能的封裝,只不過(guò)粒度不一樣吴裤。我們本文中所指的組件化旧找,和上述3中提到的模塊化是一致的。

插件化與組件化

  1. 一套完整的插件化或組件化都必須能夠?qū)崿F(xiàn)單獨(dú)調(diào)試嚼摩、集成編譯钦讳、數(shù)據(jù)傳輸、UI 跳轉(zhuǎn)枕面、生命周期和代碼邊界這六大功能愿卒。

  2. 插件化和組件化最重要而且是唯一的區(qū)別的就是:插件化可以動(dòng)態(tài)增加和修改線上的模塊,組件化的動(dòng)態(tài)能力相對(duì)較弱潮秘,只能對(duì)線上已有模塊進(jìn)行動(dòng)態(tài)的加載和卸載琼开,不能新增和修改。

  3. 插件化讓我們的App的運(yùn)行的時(shí)候能夠動(dòng)態(tài)的進(jìn)行組裝枕荞,就像我們使用chrome的插件一樣柜候,非常的方便,甚至演變到后期躏精,插件化越來(lái)越像[虛擬機(jī)]發(fā)展渣刷,使用一個(gè)類(lèi)似[boot]的殼,就可以像Java虛擬機(jī)加載Java文件一樣加載一個(gè)App矗烛。插件化主要涉及對(duì)系統(tǒng)加載dex的依賴(lài)辅柴,所以適配起來(lái)坑比較多。

  4. 組件化可以說(shuō)和插件化有異曲同工之妙瞭吃,只不過(guò)插件化是在[運(yùn)行時(shí)]碌嘀,而組件化是在[編譯時(shí)]。換句話說(shuō)歪架,插件化是基于多APK的股冗,而組件化本質(zhì)上還是只有一個(gè)APK。編譯一個(gè)大型App的時(shí)間時(shí)間很長(zhǎng)和蚪,可能2止状,3分鐘都不夠.[組件化] 就可以很好的解決這樣的問(wèn)題,此外攒霹,由于整個(gè)App的各個(gè)業(yè)務(wù)被分離了导俘,所以它們之間的耦合度也就被降低了,各個(gè)業(yè)務(wù)線可以由專(zhuān)門(mén)的開(kāi)發(fā)同學(xué)進(jìn)行開(kāi)發(fā)剔蹋,相互之間也不會(huì)有干擾旅薄,提升開(kāi)發(fā)效率

組件化詳細(xì)方案

代碼組件之間解耦

按照業(yè)務(wù)邏輯劃分模塊,對(duì)于一般app來(lái)說(shuō),可以分為三層。

  1. 基礎(chǔ)庫(kù)(比如網(wǎng)絡(luò)庫(kù)少梁,數(shù)據(jù)庫(kù)洛口,utils,圖片加載庫(kù))
  2. 基礎(chǔ)模塊凯沪,但是沒(méi)有獨(dú)立運(yùn)行調(diào)試的必要第焰,一般只是當(dāng)作com.android.library被別的獨(dú)立模塊引用(比如登陸模塊,分享模塊妨马,視頻播放模塊)
  3. 業(yè)務(wù)模塊挺举,可以進(jìn)行單獨(dú)編譯,打包烘跺,測(cè)試(比如拍攝模塊湘纵,搜索模塊,視頻流模塊滤淳,小視頻模塊)

這三個(gè)層次只能向下依賴(lài)梧喷,比如3層依賴(lài)2層,2層依賴(lài)1層脖咐。每一層里面互相不能依賴(lài)铺敌。
這符合依賴(lài)倒置原則

業(yè)界模塊劃分的例子

  • 安居客


    4.jpg
  • 滴滴組件化的圖


    3.jpg
  • 微信

6.png

組件工程單獨(dú)開(kāi)發(fā)調(diào)試

先來(lái)看看Android組件化需要實(shí)現(xiàn)的目標(biāo)。(什么是組件化構(gòu)建屁擅?)

  1. 項(xiàng)目模塊能夠單獨(dú)啟動(dòng)測(cè)試
  2. 能夠根據(jù)需求引入或刪除某些業(yè)務(wù)模塊
  3. 通過(guò)不同模塊的組合偿凭,組成不同的App

對(duì)于第一點(diǎn):Android是通過(guò)應(yīng)用com.android.application或com.android.library來(lái)決定該模塊是以App模式還是以Library模式構(gòu)建。App模式和Library模式的最大區(qū)別就是派歌,App能夠啟動(dòng)弯囊,而Library不可以。所以如果我們的模塊能獨(dú)立啟動(dòng)的話硝皂,我們需要每次手動(dòng)去改動(dòng)模塊的build.gradle文件。好一點(diǎn)的做法定義一個(gè)布爾值來(lái)判斷是否處于debug模式作谭,但是這里有個(gè)問(wèn)題是稽物,不是每個(gè)模塊都能獨(dú)立啟動(dòng)的。所以無(wú)論采用何種方案折欠,都需要我們手動(dòng)管理贝或。

對(duì)于第二點(diǎn):當(dāng)我們開(kāi)發(fā)好業(yè)務(wù)模塊后,可能我們需要頻繁的新增或刪除某些業(yè)務(wù)模塊锐秦。如果是這樣的話咪奖,我們也是需要頻繁手動(dòng)修改App的build.gradle。

對(duì)于第三點(diǎn):有時(shí)候酱床,我們可能會(huì)在不同的App中引用相同的組件(例如:滴滴的普通版和企業(yè)版羊赵,普通版包含企業(yè)版的功能),這個(gè)時(shí)候,我們也不希望要頻繁手動(dòng)管理組件依賴(lài)昧捷,特別是在組件還可以獨(dú)立運(yùn)行的時(shí)候闲昭。

所以,在我們實(shí)踐組件化的時(shí)候靡挥,最大的問(wèn)題就是序矩,我們需要頻繁的手動(dòng)build.gradle文件來(lái)管理組件應(yīng)用的插件和App的依賴(lài)。

對(duì)于這一部分跋破,主要的就是開(kāi)發(fā)一個(gè)gradle插件簸淀,對(duì)工程進(jìn)行自動(dòng)化管理,避免人為切換導(dǎo)致的各種錯(cuò)誤毒返。

組件之間互相通信

由于組件之間完全解耦租幕,互相無(wú)法直接進(jìn)行調(diào)用,所以通過(guò)接口+實(shí)現(xiàn)的結(jié)構(gòu)進(jìn)行組件間的通信饿悬。每個(gè)組件聲明自己提供的服務(wù) Service API令蛉,這些 Service 都是一些接口,組件負(fù)責(zé)將這些 Service 實(shí)現(xiàn)并注冊(cè)到一個(gè)統(tǒng)一的路由 Router 中去狡恬,如果要使用某個(gè)組件的功能珠叔,只需要向Router 請(qǐng)求這個(gè) Service 的實(shí)現(xiàn),具體的實(shí)現(xiàn)細(xì)節(jié)我們?nèi)徊魂P(guān)心弟劲,只要能返回我們需要的結(jié)果就可以了祷安。在組件化架構(gòu)設(shè)計(jì)圖中 Common 組件就包含了路由服務(wù)組件,里面包括了每個(gè)組件的路由入口和跳轉(zhuǎn)兔乞。

由于各個(gè)模塊是嚴(yán)格劃分解耦的汇鞭,各個(gè)模塊對(duì)與彼此的存在是完全不知道的,所以各個(gè)組件的互相通信就需要一個(gè)通用的協(xié)議來(lái)進(jìn)行庸追。于是引入了路由框架霍骄。

8.png

通過(guò)上圖可以看到,我們?cè)谧罨A(chǔ)的Common庫(kù)中淡溯,創(chuàng)建了一個(gè)路由Router读整,中間有n個(gè)模塊Module,這個(gè)Module實(shí)際上就是Android Studio中的module咱娶,這些Module都是Android Library Module米间,最上面的Module Main是可運(yùn)行的Android Application Module。

這幾個(gè)Module都引用了Common庫(kù)膘侮,同時(shí)Main Module還引用了A屈糊、B、N這幾個(gè)Module琼了,經(jīng)過(guò)這樣的處理之后逻锐,所有的Module之間的相互調(diào)用就都消失了,耦合性降低,所有的通信統(tǒng)一都交給Router來(lái)處理分發(fā)谦去,而注冊(cè)工作則交由Main Module去進(jìn)行初始化慷丽。這個(gè)架構(gòu)思想其實(shí)和Binder的思想很類(lèi)似,采用C/S模式鳄哭,模塊之間隔離要糊,數(shù)據(jù)通過(guò)共享區(qū)域進(jìn)行傳遞。模塊與模塊之間只暴露對(duì)外開(kāi)放的Action妆丘,所以也具備面向接口編程思想锄俄。

圖中的紅色矩形代表的是行動(dòng)Action,Action是具體的執(zhí)行類(lèi)勺拣,其內(nèi)部的invoke方法是具體執(zhí)行的代碼邏輯奶赠。如果涉及到并發(fā)操作的話,可以在invoke方法內(nèi)加入鎖药有,或者直接在invoke方法上加上synchronized描述毅戈。

圖中的黃色矩形代表的是供應(yīng)商Provider,每個(gè)Provider中包含1個(gè)或多個(gè)Action愤惰,其內(nèi)部的數(shù)據(jù)結(jié)構(gòu)以HashMap來(lái)存儲(chǔ)Action苇经。首先HashMap查詢(xún)的時(shí)間復(fù)雜度是O(1),符合我們對(duì)調(diào)用速度上的要求宦言,其次扇单,由于我們是統(tǒng)一進(jìn)行注冊(cè),所以在寫(xiě)入時(shí)并不存在并發(fā)線程并發(fā)問(wèn)題奠旺,在讀取時(shí)蜘澜,并發(fā)問(wèn)題則交由Action的invoke去具體處理。在每一個(gè)Module內(nèi)都會(huì)有1個(gè)或多個(gè)供應(yīng)商Provider(如果不包含Provider响疚,那么這個(gè)Module將無(wú)法為其他Module提供服務(wù))鄙信。

途中藍(lán)色矩形代表的是路由Router,每個(gè)Router中包含多個(gè)Provider忿晕,其內(nèi)部的數(shù)據(jù)結(jié)構(gòu)也是以HashMap來(lái)存儲(chǔ)Provider装诡,原理也和Provider是一樣的。之所以用了兩次HashMap杏糙,有兩點(diǎn)原因慎王,一個(gè)是因?yàn)檫@樣做蚓土,不容易導(dǎo)致Action的重名宏侍,另一個(gè)是因?yàn)樵谧?cè)的時(shí)候,只注冊(cè)Provider會(huì)減少注冊(cè)代碼蜀漆,更易讀谅河。并且由于HashMap的查詢(xún)時(shí)間復(fù)雜度是O(1),所以?xún)纱尾檎也粫?huì)浪費(fèi)太多時(shí)間。當(dāng)查找不到對(duì)應(yīng)Action的時(shí)候绷耍,Router會(huì)生成一個(gè)ErrorAction吐限,會(huì)告之調(diào)用者沒(méi)有找到對(duì)應(yīng)的Action,由調(diào)用者來(lái)決定接下來(lái)如何處理褂始。

一次請(qǐng)求流程
通過(guò)Router調(diào)用的具體流程是這樣的:

9.png

任意代碼創(chuàng)建一個(gè)RouterRequest诸典,包含Provider和Action信息,向Router進(jìn)行請(qǐng)求崎苗。
Router接到請(qǐng)求狐粱,通過(guò)RouterRequest的Provider信息,在內(nèi)部的HashMap中查找對(duì)應(yīng)的Provider胆数。
Provider接到請(qǐng)求肌蜻,在內(nèi)部的HashMap中查找到對(duì)應(yīng)的Action信息。
Action調(diào)用invoke方法必尼。
返回invoke方法生成的ActionResult蒋搜。
將Result封裝成RouterResponse,返回給調(diào)用者判莉。
上述描述豆挽,引用:Android架構(gòu)思考

這只是一個(gè)原理性的描述,不同的開(kāi)源框架具體實(shí)現(xiàn)細(xì)節(jié)可能不同骂租,想了解具體實(shí)現(xiàn)細(xì)節(jié)祷杈,可以研究一下開(kāi)源路由代碼。

開(kāi)源框架實(shí)現(xiàn):

  • WMRouter(美團(tuán)方案)
  • ARouter(阿里方案)
  • Andromeda(支持跨進(jìn)程)
  • DDComponentForAndroid(得到方案)
  • ModularizationArchitecture(支持跨進(jìn)程)

UI 跳轉(zhuǎn)問(wèn)題

可以說(shuō) UI 跳轉(zhuǎn)也是組件間通信的一種渗饮,但是屬于比較特殊的數(shù)據(jù)傳遞但汞。不過(guò)一般 UI 跳轉(zhuǎn)基本都會(huì)單獨(dú)處理,一般通過(guò)短鏈的方式來(lái)跳轉(zhuǎn)到具體的 Activity互站。每個(gè)組件可以注冊(cè)自己所能處理的短鏈的 Scheme 和 Host私蕾,并定義傳輸數(shù)據(jù)的格式,然后注冊(cè)到統(tǒng)一的 Router 中胡桃,Router 通過(guò) Scheme 和 Host 的匹配關(guān)系負(fù)責(zé)分發(fā)路由踩叭。但目前比較主流的做法是通過(guò)在每個(gè) Activity 上添加注解,然后通過(guò) APT 形成具體的邏輯代碼翠胰。

目前開(kāi)源的框架有:

  • ARouter 框架容贝,通過(guò)注解方式進(jìn)行頁(yè)面跳轉(zhuǎn),阿里出品
  • ActivityRouter
  • WMRouter 美團(tuán)開(kāi)源框架
  • DeepLinkDispatch

資源沖突

  • 對(duì)于多個(gè) Bussines Module 中資源名沖突的問(wèn)題之景,可以通過(guò)在 build.gradle 定義前綴的方式解決:
defaultConfig {
   ...
   resourcePrefix "new_house_"
   ...
}
  • 多個(gè)mainfest問(wèn)題
    每個(gè)可以獨(dú)立運(yùn)行的組件斤富,都需要自己獨(dú)立的mainfest,根據(jù)組件是否是獨(dú)立運(yùn)行锻狗,配置不同的Manifest路徑
sourceSets {
    main {
        if (isDebug.toBoolean()) {
            manifest.srcFile 'src/debug/AndroidManifest.xml'
        } else {
            manifest.srcFile 'src/release/AndroidManifest.xml'
        }
    }
}

組件加載

  • 多個(gè)application的問(wèn)題
    可以嘗試用兩種方式
    • 字節(jié)碼插入模式是在dex生成之前满力,掃描所有的ApplicationLike類(lèi)(其有一個(gè)共同的父類(lèi))焕参,然后通過(guò)javassist在主項(xiàng)目的Application.onCreate()中插入調(diào)用ApplicationLike.onCreate()的代碼。這樣就相當(dāng)于每個(gè)組件在application啟動(dòng)的時(shí)候就加載起來(lái)了油额。

    • 反射調(diào)用的方式是手動(dòng)在Application.onCreate()中或者在其他合適的時(shí)機(jī)手動(dòng)通過(guò)反射的方式來(lái)調(diào)用ApplicationLike.onCreate()叠纷。之所以提供這種方式原因有兩個(gè):對(duì)代碼進(jìn)行掃描和插入會(huì)增加編譯的時(shí)間,特別在debug的時(shí)候會(huì)影響效率潦嘶,并且這種模式對(duì)Instant Run支持不好涩嚣;另一個(gè)原因是可以更靈活的控制加載或者卸載時(shí)機(jī)。

對(duì)于1掂僵,2方案缓艳,具體可以查看得到(DDComponentForAndroid)方案中的實(shí)現(xiàn)。

業(yè)內(nèi)一些組件化開(kāi)源方案

  • 得到方案(DDComponentForAndroid)
  • CC(ComponentCaller)看峻,漸進(jìn)式組件方案
  • ModularizationArchitecture
  • Atlas(阿里方案)

可行性(組件化與****項(xiàng)目如何結(jié)合)

綜上所述阶淘,組件化是一個(gè)系統(tǒng)性工程,需要從編譯互妓,代碼結(jié)構(gòu)溪窒,通信框架,打包冯勉,測(cè)試等各個(gè)環(huán)節(jié)進(jìn)行重構(gòu)澈蚌。
對(duì)于已有的app來(lái)說(shuō),采用漸進(jìn)式的組件化是比較穩(wěn)妥地方式灼狰。
下面針對(duì)****進(jìn)行一些分析宛瞄,將****中的module庫(kù)進(jìn)行一個(gè)劃分

  • 基礎(chǔ)庫(kù)

      baseAppInfoLib
      common-lib-net
    
  • 功能庫(kù)

      sohuUpload
      downloadsdk
      sohuMediaPlayerSdk
      sohuMediaPlayerLib
      sohuDanmuLib
      scaleview 
      sohuVideoEditor 
      sohuPrivilegeLib
    
  • 組件庫(kù)

      qianliyanlib
      sohuVideoMobile
      fivesixapp
    

短期規(guī)劃

目前拍攝模塊(qianliyanlib)相對(duì)獨(dú)立,先從拍攝模塊進(jìn)行解耦

首先與拍攝模塊有直接耦合關(guān)系的是上傳視頻組件交胚,上傳視頻組件中份汗,耦合了一部分視頻轉(zhuǎn)碼的狀態(tài)展示。
可以考慮先將拍攝模塊與上傳模塊先行進(jìn)行組件化蝴簇。兩個(gè)模塊中的狀態(tài)互相依賴(lài)杯活,則通過(guò)注冊(cè)各自模塊提供的service進(jìn)行接口編程方式實(shí)現(xiàn)。

后期如果有新的需求熬词,并且是比較大的功能模塊旁钧,那么就直接用組件模式進(jìn)行開(kāi)發(fā)。

通過(guò)這個(gè)組件化后互拾,整個(gè)拍攝模塊與上傳模塊歪今,就可以單獨(dú)調(diào)試與運(yùn)行,在解耦過(guò)程中颜矿,逐步探索組件化的一些細(xì)節(jié)寄猩。為后期整體app組件化積累經(jīng)驗(yàn)。

后期規(guī)劃

可以按照功能模塊進(jìn)行劃分如下:

  1. 紅包模塊
  2. 搜索模塊
  3. 商場(chǎng)訂單模塊
  4. 首頁(yè)框架模塊
  5. 小視頻播放模塊(包含列表與詳情)
  6. 視頻信息流模塊(包含首頁(yè)tab或衡,熱點(diǎn)tab焦影,訂閱流,包含流播放封断,視頻詳情中播放)
  7. 個(gè)人中心模塊

參考資料

http://blog.spinytech.com/2016/12/28/android_modularization/

https://github.com/luckybilly/AndroidComponentizeLibs

https://mp.weixin.qq.com/s/6Q818XA5FaHd7jJMFBG60w

http://blog.zhaiyifan.cn/2016/10/20/android-new-project-from-0-p11/

https://mp.weixin.qq.com/s/6Q818XA5FaHd7jJMFBG60w

http://zjutkz.net/2016/10/07/%E5%85%B3%E4%BA%8EAndroid%E4%B8%9A%E5%8A%A1%E7%BB%84%E4%BB%B6%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E8%80%83/

http://www.trinea.cn/android/didi-internationalization-android-evolution/

http://tangpj.com/2018/07/22/calces-componentization/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斯辰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坡疼,更是在濱河造成了極大的恐慌彬呻,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柄瑰,死亡現(xiàn)場(chǎng)離奇詭異闸氮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)教沾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)蒲跨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人授翻,你說(shuō)我怎么就攤上這事或悲。” “怎么了堪唐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵巡语,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我淮菠,道長(zhǎng)男公,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任合陵,我火速辦了婚禮枢赔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拥知。我一直安慰自己糠爬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布举庶。 她就那樣靜靜地躺著执隧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪户侥。 梳的紋絲不亂的頭發(fā)上镀琉,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音蕊唐,去河邊找鬼屋摔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛替梨,可吹牛的內(nèi)容都是我干的钓试。 我是一名探鬼主播装黑,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼弓熏!你這毒婦竟也來(lái)了恋谭?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤挽鞠,失蹤者是張志新(化名)和其女友劉穎疚颊,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體信认,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡材义,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嫁赏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片其掂。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖潦蝇,靈堂內(nèi)的尸體忽然破棺而出清寇,到底是詐尸還是另有隱情,我是刑警寧澤护蝶,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布华烟,位于F島的核電站,受9級(jí)特大地震影響持灰,放射性物質(zhì)發(fā)生泄漏盔夜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一堤魁、第九天 我趴在偏房一處隱蔽的房頂上張望喂链。 院中可真熱鬧,春花似錦妥泉、人聲如沸椭微。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蝇率。三九已至,卻和暖如春刽沾,著一層夾襖步出監(jiān)牢的瞬間本慕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工侧漓, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锅尘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓布蔗,卻偏偏與公主長(zhǎng)得像藤违,于是被迫代替她去往敵國(guó)和親浪腐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評(píng)論 25 707
  • 用兩張圖告訴你顿乒,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料议街? 從這篇文章中你...
    hw1212閱讀 12,723評(píng)論 2 59
  • iOS組件化方案探索 一、什么是組件化淆游? 1、什么是組件隔盛? "組件"一般來(lái)說(shuō)用于命名比較小的功能塊犹菱,如:下拉刷新組...
    yehot閱讀 16,084評(píng)論 14 207
  • 從小到大,我認(rèn)識(shí)很多人吮炕,也有很多朋友腊脱,有高的矮的胖的瘦的,有男的女的有文化的和文化水平不太高的龙亲,有活潑的有喜歡安靜...
    田野虎閱讀 343評(píng)論 0 3
  • 題目寫(xiě)的是2018年剛開(kāi)始的4個(gè)小時(shí)陕凹,但其實(shí)我真正要寫(xiě)的應(yīng)該是從2017年最后一天的下午7點(diǎn)到2018年剛開(kāi)始的第...
    CY_M閱讀 129評(píng)論 0 1