淺談安卓項目框架發展

NanTorres 8年前發布 | 15K 次閱讀 Android開發 移動開發

來自: http://blog.csdn.net//guijiaoba/article/details/50223227


淺談安卓項目框架發展


翻譯自Android Application Architecture

Android開發的生態環境變化非常快,每時每刻都會有一些新的庫和工具產生。

2012年前

2012年的時候,當時安卓程序的主要框架是,沒有什么網絡請求庫。任何耗時操作都是使用AsyncTasks完成。基本框架圖如下所示。
2012

代碼中只有2層:數據層、UI層。

  • 數據層:使用REST API來請求數據,保存數據,為界面提供數據的支持。
  • UI層:顯示數據層的數據,同時處理用戶的事件。

同時會APIProvider來提供一些接口方法,給Activity或Fragment來調用請求數據,APIProvider內部使用URLConnection結合AsyncTasks的方式,來請求數據。當數據回來后,通過一些列的回調給Activity和Fragment。

CacheProvider用來保存一些緩存數據,如SharedPreferences來保存簡單數據,用SQLite來保存復雜的數據,當然CacheProvider也會提供一些回調給UI層。

問題

通過以上的方法來架構程序,會使的UI層很重。比如,程序中有個功能是用ListView來加載圖片的場景,同時用sqlite緩存的技術。那么正常情況下,Activity需要做如下的操作。

  1. 調用APIProvider中loadPosts(callback) 的方法。
  2. 在回調中等待獲取數據成功,然后再調用CacheProvider的savePosts(callback)方法來緩存數據。
  3. 等待數據保存成功后,然后再把數據顯示在ListView中。
  4. 假如某一步失敗了,那么還要在某個回調中單獨處理。

這是一個比較簡單的例子。在實際的情況下,REST API可能會返回一個復雜的數據,Activity可能需要對數據做一些處理,才能顯示。比如其他一些使用場景,要從Play Server SDK中異步加載郵件名稱,那么在代碼中可能會有回調方法嵌套的問題。如果這種回調嵌套太多,那么對于程序來說,簡直是一團糟,一個大坑。

總結

  1. Activity和Fragment會變得非常龐大,并且難以維護。
  2. 太多的回調嵌套,不方便未來代碼的擴展。
  3. 不能進行單元測試,有很多的邏輯代碼放在UI層,就非常難以測試。

使用RxJava架構

上面的說的程序框架我們使用2年多,當然我們也做了一些修改。比如,我們在APIProvider中使用Volley來進行網絡請求。然后我們的代碼就變得非常難以測試,掉進一個回調嵌套的大坑里面。
2014年的時候,我們開始了解到RxJava,自己也經常寫一些小的Demo,發現它可以解決回調嵌套問題。如果你還不了解RxJava,你可以在這里了解到。簡單來說,Rxjava可以讓你的異步方法變成流一樣處理,同時你還可以對流中數據的進行轉化、過濾、組合等。
使用Rxjava后,我們的項目結構變成如下所示。

Rxjava

相對于來第一個版本的架構來說,我們對數據層和UI層進行了分離。數據層變成了一個數據管理類(DatManager),數據管理類會持有很多數據幫助類(Helper classes)。UI層就是使用安卓系統提供的組件來顯示數據,如Fragment,Activity,ViewGroup等。

數據幫助類(Helper classes)通常是一些第三方的框架和庫,用來保存和處理數據,很方便。比如通過REST API接口來獲取數據,就可以使用第三方的工具。不同的程序獲取數據方式是不同的,但是相同點是:

  1. PreferencesHelper可以保存和讀取SharedPreferences中的數據。
  2. DatabaseHelper可以訪問數據庫
  3. Retrofit Services可以訪問web服務器中的數據,我們把Volley替換成Retrofit,因為Retrofit提供RxJava方式的調用接口。

項目中大部分的public方法都變成了RxJava Observables的方式。

DataManager就是整個項目的大腦,它使用Rxjava的方式,從各種幫助類中獲取數據,然后對數據進行處理,最后把數據傳給界面層,界面層不再需要關心怎么處理數據了,直接用來顯示。

比如我們需要一個顯示博客內容,整個一個流程如下所:

  1. 通過REST API來獲取一個博客的列表。
  2. 使用DatabaseHelper來保存獲取到的數據。
  3. 當我們需要現在在界面中過濾顯示今日所寫的博客時候,就可以使用Rxjava對數據進行過濾。

UI層中組建只需要調用簡單調用某個方法,然后會使用Rxjava中Observable來接受數據。或者可以通過適配器模式,來顯示在不同的組建中。

最后我們在項目中使用了EventBus。EventBus就像安卓系統的中廣播一樣,可以隨時在數據層發送一個事件,然后界面中的可以有多個組建來接受這個事件。比如我有個退出登錄操作,數據層在調用signOUt方法后,發送一個退出登錄的事件。那么各種Activity都會受到這個事件,然后對界面上顯示的數據進行刷新。

新架構的優點

  1. RxJava提供統一的Observables和操作,這樣可以去除回調嵌套
  2. DataManager持有多個業務數據的倉庫,這樣Activity和Fragment只需要負責顯示,無需做過多的數據操作。
  3. 把數據從UI層移動到DataManager中,這樣很方便進行單元測試。
  4. 職責分明,DataManager只需要關注數據的存儲和處理,同時使程序變得容易測試。各種幫助類,也很方便的mock數據。

新架構的缺點

  1. DataManager將變的非常的大,非常難以維護。
  2. 雖然UI層變得非常簡單,只需要負責顯示數據。但是它還需要在Rxjava的回調中處理一些其他的業務邏輯。

MVP架構

又過一年左右,有一些新的架構方式出現。比如MVP和MVVM已經在社區變的流行起來。通過幾個Demo和文章,我們發現MVP可以對我們現在的架構做出優化。因為當前的架構的只有2層,添加一個MVP很方便自然。添加了MVP后,我們的架構變成了這樣。

MVP

現在的數據層已經變成了Model,更加清楚明了。

Presenters是把原先在Datamanager中加載數據的方法移動到Presenters中,當界面需要加載數據時候,只需要調用Presenters即可。當然也是采用Rxjava的方式。同時Presenters可以對加載數據錯誤,進行適當的處理,這樣比把所有的數據處理放在DataMangager中要好。

最后發現Presenters中的public方法跟都是使用Rxjava中的調用方式,然后Rxjava在調用DataManager中方法。

MVPView是一個顯示接口,用來顯示Presenters返回的數據,通常都是Activity、Fragment、ViewGroup來實現這個接口,然后再去顯示數據。

相對于第二個版本,我們發現UI層通含就是安卓系統提供的組件,如ViewGroup、Activity、Fragment。主要的不同的是,對不同Observables做不同的處理。
所以可以提供一個通用的數據展示方法,比如showError() or showProgressIndicator()。同時界面組件只需要處理一些事件就可以了,比如按鈕的點擊事件,然后加載數據,顯示數據。

MVP資料

Github

Guidelines

優點

  1. Activity和Fragment變得更加輕量級,只需要處理用戶的響應,加載數據,顯示數據即可。
  2. 我們可以很方便的對Presenters進行修改,同時也可以mock些測試數據,這樣頁面測試也變的很方便。
  3. 假如Data Manager變的很大,可以把部分代碼移動到Presenters中。

問題

  • DataManager是一個單例,并且這個單利非常大也很復雜。暫時還沒有很好的方法能夠解決。

很顯然,這不是一個完美的程序架構。實際上,并沒有一個好的架構能夠解決所有的問題。但是安卓的生態圈一直都在不斷的發展,同時我們自己也要不斷的探索,使我么你的程序更加健壯和優秀。

我希望你能喜歡這篇文章,同時也想這片文章對你有所益處。如問題,可以聯系我。

</div>

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