千萬級用戶的Android客戶端是如何養成的

luo1989717 8年前發布 | 5K 次閱讀 安卓開發 移動開發

Android客戶端的架構不論如何演變,架構設計的出發點總是離不開兩點,一是提高開發效率,二是降低維護成本。阿劉基于這兩點,主要分享了in Android客戶端的架構演變。以下是正文:

1.0 時代:小、快、靈

2014年6月份,in發布了第一個版本。到目前為止,已經經歷了幾十個版本的迭代。在1.0時代,APP的特點是小、快、靈。當時產品邏輯并不復雜,投入的資源不是特別多。因為處于探索期,所以產品的迭代非常快,為了與之適應,in采用了簡單的單工程的形式組織整個產品結構,高結構的層次也只有幾層,非常淺,如圖1所示。

圖 1

為了兼容H5跳轉,in參考了H5的一種路由協議作為跳轉的支持。該時期,in的用戶量增長迅速,1.0末期已經達到了近2500萬。在這個框架下,in一直衍生到1.9版本,這段時期使用輕量結構比較適合小步快走,即迭代非常快的形式,但這種形式存在一個明顯的缺點,即擴展性較差,個別類臃腫,不適合協同開發。隨著業務邏輯愈發復雜,參與人員不斷增加,如何提高協同開發效率成為當務之急。

2.0時代:繁、穩

in在2.0時代有三個亟需解決的問題:

  • 產品邏輯日趨復雜。復雜表現在兩方面:一是演進非常快;二是反復。這是最致命的,因為開發過程中PD可能會臨時做一些需求上的變更。因此,此時的框架必須適應產品的復雜化;
  • 代碼復用性差。1.0時代,新模塊的開發主要基于原有的模塊,僅僅在原有的模塊上做一個很小的改動,代碼實現上卻需要進行大幅度的調整;
  • 業務邏輯與基礎功能雜糅在一起。因為業務上的一些變更常常會觸及底層的東西,導致穩定性不足。

圖 2

基于這三點,in在2.0時代進行了如圖2所示的重構。

首先,將所有業務分成獨立的模塊,同時考慮產品邏輯中可能沒有想到的模塊。以in為例,in有圖片詳情頁,但從產品邏輯看,產品分為個人中心、話題、品牌站等模塊,這些模塊都有各自的圖片詳情頁,圖片詳情頁并不是一個獨立的業務線。初期,in嚴格按照產品線去劃分業務邏輯模塊,所以開發出好幾套圖片詳情頁,這就是代碼復用性差。經驗教訓是,模塊不應完全由PD決定,我們必須非常熟悉產品結構,清楚有沒有共性的模塊可以單獨抽離出來。

其次,業務模塊必須具有一定的配置性,即可擴展性。沿用剛才的例子,我們希望個人中心的圖片詳情頁具有顯示用戶打上去的標簽、貼紙等的功能,但品牌詳情頁可能并不需要這類功能,所以業務模塊必須達到可配置。分好業務模塊后,各個模塊之間相互獨立,但必然存在公共的功能,因此需要有一個底層的公共類庫做支持。公共類庫主要包括了一些基礎功能,比如網絡請求、圖片解析、本地日志系統等。

最后,in引入了許多第三方功能,而公共模塊是一個獨立工程。in允許公共模塊直接使用第三方庫,但不允許其它模塊單獨使用。因此,第三方庫達到統一管理。同時,in還沿用并強化了1.0時代的路由協議,推送可以通過這套協議跳轉到推送頁面。

到此,in基本解決了之前談到的三個問題,更重要的是提高了QA測試效率。

以往需要等所有功能開發完成才能交付給QA,分模塊后,每一個業務模塊都可以不依賴其他模塊獨立運行。當一個模塊自己的業務開發完成后,都可直接交付給QA。但與此同時,產品又產生了新的問題,即公共類庫臃腫,難維護,遷移成本高。

2.0時代,in的用戶量從1.0時代的近2500萬增長到7000萬。in意識到每一次小的更新都會影響用戶的體驗,因此告別了原先快速迭代的發展模式,轉為求穩。從開發的角度來說,是要提供更優質的服務。

后2.0時代:精、穩

圖 3

針對2.0時代產品公共類庫臃腫的問題,in在框架上做了如圖3所示的改進。首先,上層沿用2.0時代的形式,但對公共模塊進行拆分,將公共業務抽成代理層,并且引入服務化的概念,將每一個機組功能都抽成獨立的服務,比如網絡請求、圖片上傳,本地日志等。這一版改進后,服務都被獨立抽出,相互之間是隔離的,每個服務都可以交由不同的人去維護,內部高類聚。

與此同時,每個服務都需要有容錯性,每個模塊都需要有兜底方案,保證自己的輸出是穩定的,自己內部的問題不會影響其他服務。

另外,底層服務很少被上層的業務代碼入侵,可盡量通過協議或者是API的形式支持上層的業務邏輯,做到最輕量化級的接入。in還對第三方庫做了封裝,將其通過代理的模式與自己的業務代碼隔離,這樣就可以靈活地替換第三方類庫,并且大大降低維護成本。

服務化過程中,in沿用了之前的通信模塊,并且加入了一個統計框架。這個框架著重突出了服務化的概念,并且是本地服務化。它的優勢在于非常的獨立,且具有很高的擴展性,每加入一個新的服務,都不會影響到其他的服務,并且在整個架構的層面上來講,每一個服務之間相互依賴的關系、調用的順序都可以很快地整理出來。同時,它還給in的產品矩陣打下了一個很好的基礎,未來如果推出一些新的APP,需要引用in老的代碼時,只需要選擇需要接入的那些服務,就能很快理出新的APP的架構圖,并且配置起來。

Extra:巧、宜

圖 4

 

圖4為in內統計框架,最大的特點是自動化、無侵入式。業界很多統計框架在路徑統計層面,主要是統計Activity層以及Fragment層,但是in的很多頁面是通過View等其他形式實現的,因此無法通過現有的一些統計框架進行頁面統計。對此,in把所有的頁面都抽成layer的抽象概念,把所有的layer通過用戶的行為路徑壓到一個layer棧內,最終以一個列表的形式發到服務器,然后在服務器建立一個數據倉庫,再通過BI部門整理數據倉庫得出每個用戶的實際瀏覽路徑,包括每個頁面的留存等。

模塊內的解耦

圖 5

 

耦合存在每個模塊內。業界很常見的是用MVC、MVP等模式進行一定的解耦,in主要用MVP模式。為什么in之前Activity常常寫得特別臃腫?因為它不僅做了Model層的事,而且做了表現以及控制上的事。解決辦法是把View層單獨抽離,由Fragment去做View層的展現,而Activity層只專注于對數據的處理,實現View層跟Model層之間不直接交互,而是通過一個接口的形式進行溝通。

灰度發布機制

灰度發布機制主要是為了支持產品的A/B Test。in的產品越來越復雜,用戶量越來越多,為了實驗性的功能不影響所有的用戶體驗,只能允許一部分特定用戶看到新功能,而這需要通過代碼層做控制,即灰度發布機制。如圖5所示,灰度發布主要在業務層之上,它的配置全部由服務器端決定,確保每個業務都可以做到灰度發布。

模塊間通信

模塊增加后,模塊間通信成為一個大問題,因為模塊之間是不可見的。兩個解決辦法:第一是通過一套反射機制達到每個模塊間相對可見;第二是建立一套自己的基于觀察者、訂閱者模式的消息分發機制,in的這套機制主要參考了EventBus以及谷歌最近開源的一個安卓響應式框架Agera類似于RxAndroid,這個框架能幫助模塊間通信的現成模型的構建。另外,模塊間通信有一個Sticky機制,問題就在于當頁面未打開之前,數據已經先到了,那么該如何解決?就是通過Sticky機制,它能確保數據先到,頁面再打開的時候,數據能順利下發。

總結

每一套框架都有自己的特點,但是萬變不離其宗,最主要的是要適合當前的項目規模和體量,更好的與業務結合在一起,提高開發效率,降低維護成本。

來自:http://www.androidchina.net/5532.html

 

 本文由用戶 luo1989717 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!