Android官方MVP架構示例項目解析

App架構在Android開發者中一直是討論比較多的一個話題,目前討論較多的有MVP、MVVM、Clean這三種。google官方對於架構的態度一直是非常開放的,讓開發者自主選擇組織和架構app的方式,期望能留給開發者更多的靈活性。

由於沒有一套權威的架構實現,現在很多App項目中在架構方面都有或多或少的問題。第一種常見問題是沒有架構,需求中的一個頁面對應項目中的一個activity或一個fragment,所有的界面響應代碼、業務邏輯代碼、數據請求代碼等等都集中在其中。第二種常見的問題是架構實現的不斷變化,不斷在各種架構間搖擺,一直找不到一個適合自己的架構。

就在近日,google在官方示例中給出了一系列不同架構的app實現,這對於一直困惑於到底該用何種架構的android開發者來說確實是福音,開發者只要根據自己項目的情況,在不同的實現中選擇一種即可,當然google也明確表示了這些示例只是用來做參考,而並不是要爲了當做標準,下面先爲大家簡單介紹下此項目。


項目介紹

Google把這個項目命名爲:Android架構藍圖。

項目地址爲:https://github.com/googlesamples/android-architecture

下面的內容引用自項目說明:

You can use these samples as a reference or as a starting point for creating your own apps. The focus here is on code structure, architecture, testing and maintainability. However, bear in mind that there are many ways to build apps with these architectures and tools, depending on your priorities, so these shouldn’t be considered canonical examples. The UI is deliberately kept simple.

穩定的samples

todo-mvp/ - 基於mvp基礎架構項目.
todo-mvp-loaders/ - 基於mvp基礎架構項目,獲取數據部分使用了Loaders架構.
todo-databinding/ - 基於mvp基礎架構項目,使用了數據綁定組件.
todo-mvp-clean/ - 基於mvp基礎架構項目,使用了clean架構的概念.
todo-mvp-dagger/ - 基於mvp基礎架構項目,使用了dagger2進行依賴注入
todo-mvp-contentproviders/ - 基於mvp基礎架構項目,使用了Content Providers
todo-mvp-rxjava/ - 基於mvp基礎架構項目, 使用RxJava進行併發和數據層抽象.

如何進行選擇

這個還是需要開發者自己來做決定,每個項目的說明文件中都說明了該實現的特性。app規模、團隊狀況、維護工作量的大小、平板是否支持、代碼簡潔程度偏好,這些都會影響你的選擇。

到了這裏,想必大家都很想一探究竟了,到底官方示例是如何實現的呢?還是那句話,源碼面前,了無祕密。爲了能夠更好的理解官方mvp架構實現,下面我們從源碼的角度來分析todo-mvp(mvp基礎架構示例)的實現。我們先從項目的整體組織方式開始,再看項目究竟使用了哪些組件,最後當然是最重要的具體mvp的實現方式。


源碼分析

項目代碼組織方式

項目含一個app src目錄,4個測試目錄,分別是androidTest(UI層測試)、androidTestMock(UI層測試mock數據支持)、test(業務層單元測試)、mock(業務層單元測試mock數據支持)。src目錄的代碼組織方式完全是按照功能來組織的,功能內部分爲xactivity、xcontract、xfragment、xpresenter四個類文件(x代表業務名稱)。

平時用到較多的另一種組織方式是按照類型,比如按照activity、adapter、fragment、contract、presenter進行劃分,不同的類文件分別放到不同的目錄中,筆者覺得兩種方式沒有什麼太大的區別,完全看個人喜好了。

組件使用

由於項目是基於gradle進行編譯的,所以我們可以從build.gradle文件看到項目依賴的全貌。

Guava

項目中使用到了Guava庫(https://github.com/google/guava),該庫是Google在基於java的項目中都會引用到得一個庫,庫中包含大約14k的方法數,是個很大的庫,其中包含了集合、緩存、併發、基本註解、字符串處理、io處理等等。項目中使用Guava庫主要是處理null這種不安全的情況,因爲一般我們在使用有可能爲null的對象時,一般會增加一次判斷,代碼如下:

這裏寫圖片描述

而如果有Guava的時候,可以通過如下方式

這裏寫圖片描述

這樣面對空的時候,就不用再多寫很多代碼了,確實是方便了很多。但是不建議爲了null安全直接引入如此大的一個庫,因爲我們都知道android apk的65k方法數限制,如果要用的話可以把源碼中涉及到得部分直接拿出來用。當然Guava中還有很多重要的功能,其他功能讀者可以自行研究,關於Guava就先到這裏了。

測試相關組件

示例項目在可測試方面做的非常好,由於對視圖邏輯(view層)和業務邏輯(presenter層)進行了拆分,所以我們就可以對UI、業務代碼分別進行測試。爲了進行UI測試引入了Espresso,爲了對業務層進行單元測試引入了junit,爲了生成測試mock對象引入了mockito,爲了支撐mockito又引入了dexmaker,hamcrest的引入使得測試代碼的匹配更接近自然語言,可讀性更高,更加靈活。

項目MVP實現方式

這節我們就具體來看官方示例到底是如何實現mvp的。這裏我們先看下總體的輪廓,關於項目中業務代碼我們僅列出了任務詳情頁(taskDetail)的相關類,其他業務代碼類似。

這裏寫圖片描述

基類

我們首先來看兩個Base接口類,BasePresenter與BaseView,兩類分別是所有Presenter與View的基類。

這裏寫圖片描述

BasePresenter中含有方法start(),該方法的作用是presenter開始獲取數據並調用view中方法改變界面顯示,其調用時機是在Fragment類的onResume方法中。

這裏寫圖片描述

BaseView中含方法setPresenter,該方法作用是在將presenter實例傳入view中,其調用時機是presenter實現類的構造函數中。

契約類

與筆者之前見到的所有mvp實現都不同,官方的實現中加入了契約類來統一管理view與presenter的所有的接口,這種方式使得view與presenter中有哪些功能,一目瞭然,維護起來也方便,實例如下

這裏寫圖片描述

activity在mvp中的作用

activity在項目中是一個全局的控制者,負責創建view以及presenter實例,並將二者聯繫起來,下面是activity中創建view及presenter的代碼

這裏寫圖片描述

我們可以從上面看到整個創建過程,而且要注意的是創建後的fragment實例作爲presenter的構造函數參數被傳入,這樣就可以在presenter中調用view中的方法了。

mvp的實現與組織

實例中將fragment作爲view層的實現類,爲什麼是fragment呢?有兩個原因,第一個原因是我們把activity作爲一個全局控制類來創建對象,把fragment作爲view,這樣兩者就能各司其職。第二個原因是因爲fragment比較靈活,能夠方便的處理界面適配的問題。我們先看view的實現,我們只挑一部分重要的方法來看

這裏寫圖片描述

上面可以看到setPresenter方法,該方法繼承於父類,通過該方法,view獲得了presenter得實例,從而可以調用presenter代碼來處理業務邏輯。我們看到在onResume中還調用了presenter得start方法,下面我們再看presenter的實現

這裏寫圖片描述

presenter構造函數中調用了view得setPresenter方法將自身實例傳入,start方法中處理了數據加載與展示。如果需要界面做對應的變化,直接調用view層的方法即可,這樣view層與presenter層就能夠很好的被劃分。

最後還剩下model層實現,項目中model層最大的特點是被賦予了數據獲取的職責,與我們平常model層只定義實體對象截然不同,實例中,數據的獲取、存儲、數據狀態變化都是model層的任務,presenter會根據需要調用該層的數據處理邏輯並在需要時將回調傳入。這樣model、presenter、view都只處理各自的任務,此種實現確實是單一職責最好的詮釋。


總結

到這裏我們就基本分析完了,我們再來整體看下官方的實現方式有哪些特性。

首先是複雜度,我們可以從上面的分析看出整體的複雜度還是較低的,易學的;然後是可測試性,由於將UI代碼與業務代碼進行了拆分,整體的可測試性非常的好,UI層和業務層可以分別進行單元測試;最後是可維護性和可擴展性,由於架構的引入,雖然代碼量有了一定的上升,但是由於界限非常清晰,各個類職責都非常明確且單一,後期的擴展,維護都會更加容易。有了這個架構之後,我們再回頭看下之前的實現是不是有很多不足,沒有關係,那麼接下來就是在項目中進行實踐的時間了。


本文轉自呂英斌

另外再給兩個鏈接
http://blog.csdn.net/lmj623565791/article/details/46596109
http://www.jianshu.com/p/9a6845b26856

發佈了37 篇原創文章 · 獲贊 26 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章