細談Android應用架構

   說真的,接觸Android編程不多,通常用visual studio的c#,vc++,c#應用架構熟悉,Java熟悉,Python熟悉,但對Android陌生,朋友說學Android好久啦,並且已經上班,他說,Android開發生態圈的節奏很是之快。每週都會有新的工具誕生,類庫的更新。我不得不學習它,其實支持Android的集成開發環境也多。 html

以Android Studio集成開發環境爲例


  2013年GoogleI/O大會首次發佈了Android Studio IDE(Android平臺集成開發環境)。它基於Intellij IDEA開發環境,旨在取代Eclipse和ADT(Android開發者工具)爲開發者提供更好的開發工具。既然Google一直在努力推廣,相信不久之後就有望遇上Eclipse。 java

  • 相比Eclipse,Android Studio IDE有本身的特色:
  • 對UI界面設計和編寫代碼有更好地支持,能夠方便地調整設備上的多種分辨率。
  • 一樣支持ProGuard工具和應用簽名。
  • 不過,目前版本的Android Studio不能在同一窗口中管理多個項目。每一個項目都會打開一個新窗口。我猜這是借鑑了Intellij IDEA的行爲,並且Google近期不會對此作出調整。
  • 支持Gradle自動化構建工具,這真是極好的,但對於剛從Eclipse平臺轉移過來的開發者來講還須要一段時間去學習和適應。

2、下載和安裝相關軟件

2.一、開發環境 

  物理機版本:Win 8(64位) react

  Java SDK版本:jdk-7u45-windows-x64(64位) android

  Android Studio版本:android-studio-bundle-135.1740770-windows c++

  注:物理機版本和Java SDK版本必需要保持一致,即:同爲64位或者同爲32位。 git

2.二、下載JDK

  我下載的是JDK1.7的版本,下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html github

  

  下載到本地電腦後雙擊進行安裝。JDK的安裝過程比較簡單,安裝過程基本上就是一路Next便可,作Java開發的人都會,在安裝的時候只須要注意將JDK和JRE安裝到同一個目錄便可,JDK默認安裝成功後,會在系統目錄下出現兩個文件夾,一個表明jdk,一個表明jre 數據庫

  

  JDK的全稱是Java SE Development Kit,也就是Java 開發工具箱。SE表示標準版。JDK是Java的核心,包含了Java的運行環境(Java Runtime Environment),一堆Java工具和給開發者開發應用程序時調用的Java類庫。
  咱們能夠打開jdk的安裝目錄下的Bin目錄,裏面有許多後綴名爲exe的可執行程序,以下圖所示:
  
  這些都是JDK包含的工具,經過配置JDK的變量環境,咱們能夠方便地調用這些工具及它們的命令。
  JDK包含的基本工具主要有:
  • javac:Java編譯器,將源代碼轉成字節碼。
  • jar:打包工具,將相關的類文件打包成一個文件。
  • javadoc:文檔生成器,從源碼註釋中提取文檔。
  • java:運行編譯後的java程序。

2.三、配置Windows上JDK的變量環境

  爲了配置JDK的系統變量環境,咱們須要設置兩個系統變量,分別是JAVA_HOME,Path。下面是這兩個變量的設置。
  一、JAVA_HOME
    先設置這個系統變量名稱,變量值爲JDK在你電腦上的安裝路徑:E:\Program Files\Java\jdk1.7.0_75建立好後則能夠利用%JAVA_HOME%做爲JDK安裝目錄的統一引用路徑。
  
  二、Path
    PATH屬性已存在,可直接編輯,在原來變量後追加:;%JAVA_HOME%\bin
  
  JDK環境變量的配置作Java開發的人都應該會,這裏就不細講了!

2.四、Android Studio下載

  下載地址:http://developer.android.com/sdk/index.html,注意,下載Android Studio要FQ才行 編程

  

  

  

  下載完成以後,獲得一個以下圖所示的安裝包: c#

  

2.五、Android Studio安裝

  下載完成後,就能夠開始安裝了,用鼠標雙擊android-studio-bundle-135.1740770-windows.exe啓動安裝程序,Android Studio安裝過程以下圖所示:

  

  AndroidStudio是集成了Android SDK的,因此在安裝的時候記得勾選上Android SDK

  

  

  

  

  

  

  這個安裝過程有點久,須要一點時間。

  

  

2.六、啓動運行Android Studio

  Android Studio啓動過程以下圖所示:

  

  

  第一次啓動AndroidStudio時,須要設置一下SDK的安裝目錄,所以會彈出以下圖所示的對話框,

  

  設置Android SDK的安裝目錄,以下圖所示:

  

  打開AndroidStudio以後,默認會幫咱們建立一個app的項目,以下圖所示:

  

  運行這個默認建立好的項目,爲了運行方便,咱們直接使用真機做爲模擬器運行,以下圖所示:

  

  注意,使用真機調試時,手機必須開啓USB調試模式才行,以下圖所示:

  

  在手機上面的運行結果以下圖所示:

  

  手機上顯示應用的桌面上也顯示出了咱們這個Android應用的圖標,以下圖所示:

  

  到此,使用Android Studio搭建Android集成開發環境的工做就所有完成了,測試也經過了!

3、Android Studio的簡單使用

3.1查看安裝好的Android SDK

  

  已經安裝好的Android SDK版本以下圖所示:

  

  咱們能夠看到,截止到今天爲止,Anddroid的版本已經更新到Android5.1(API22)了,更新速度真的很快啊,Android5.1(API22)的相關內容如今仍是處於【Not installed】狀態,也就是尚未下載和安裝,SDK Manager默認已經選中Android5.1(API22)的所有內容,咱們若是想在Android5.1(API22)的平臺下開發Android應用,那麼能夠下載Android5.1(API22)的相關內容,以下圖所示:

  

  默認下載和安裝好的Android5.0.1的開發包已經知足咱們開發Android應用的需求了,以下圖所示:

  

  固然使用eclipse,visual studio也能夠開發,具體略


先談談其Android的應用架構

能夠大體表示爲下圖。

 

代碼被劃分爲兩層結構:Data Layer(數據層)負責從REST API或者持久數據存儲區檢索和存儲數據;View Layer(視圖層)的職責是處理並將數據展現在UI上。

APIProvider提供了一些方法,使Activity和Fragment可以很容易的實現與REST API的數據交互。這些方法使用URLConnection和AsyncTask在一個單獨的線程內執行網絡請求,而後經過回調將結果返回給Activity。

按照一樣的方式,CacheProvider 所包含的方法負責從SharedPreferences和SQLite數據庫檢索和存儲數據。一樣使用回調的方式,將結果傳回Activity。

存在的問題:

使用這種結構,最主要的問題在於View Layer持有太多的職責。想象一個簡單且常見的場景,應用須要加載一個博客文章列表,而後緩存這些條目到SQLite數據庫,最後將他們展現到ListView等列表視圖上。Activity要作到如下幾個步驟:

  1. 經過APIProvider調用loadPosts方法(回調)
  2. 等待APIProvider的回調結果,而後調用CacheProvider中的savePosts方法(回調)
  3. 等待CacheProvider的回調結果,而後將這些文章展現到ListView等列表視圖上
  4. 分別處理APIProvider和CacheProvider回調中潛在的異常。

這是一個很是簡單的例子,在實際開發環境中REST API返回的數據可能並非View直接須要的。所以,Activity在進行展現以前不得不經過某種方式將數據進行轉換或過濾。另外一個常見的狀況是,調用loadPosts( )所須要的參數,須要事先從其餘地方獲取到,好比,須要Play Services SDK提供一個Email地址參數。就像SDK經過異步回調的方式返回Email地址,這就意味着如今咱們至少有三層嵌套的回調。若是繼續添加複雜的業務邏輯,這種架構就會陷入衆所周知的Callback Hell(回調地獄)

總結:

  • Activitty和Fragment變得很是龐大而且難以維護。
  • 太多的回調嵌套意味着醜陋的代碼結構並且不易讀懂和理解。若是在這個基礎上作更改或者添加新特性會感到很痛苦。
  • 單元測試變得很是有挑戰性,若是有可能的話,由於不少邏輯都留在了Activity或者Fragment中,這樣進行單元測試是很艱難的。

RxJava驅動的新型架構

咱們使用上文提到的組織架構差很少兩年的時間。在那段時間內,咱們作了一些改進,稍微緩解了上述問題。例如,咱們添加了一些Helper Class(幫助類)用來減小Activity和Fragment中的代碼,在APIProvider中使用了Volley。儘管作出了這些改變,咱們應用程序的代碼仍是不能進行友好的測試,而且Callback Hell(回調地獄)的問題仍是常常發生。

直到2014年咱們開始瞭解RxJava。在嘗試了幾個示例項目以後,咱們意識到她可能最終幫助咱們解決掉嵌套回調的問題。若是你還不熟悉響應式編程,能夠閱讀本文(譯者注:譯文點這裏那些年咱們錯過的響應式編程)。簡而言之,RxJava容許經過異步流的方式處理數據,而且提供了不少操做符,你能夠將這些操做符做用於流上從而實現轉換,過濾或者合併數據等操做

考慮到經歷了前幾年的痛苦,咱們開始考慮,一個新的應用程序體系架構看起來會是怎樣的。所以,咱們想出了這個。

 

相似於第一種架構,這種體系架構一樣被劃分爲Data LayerView LayerData Layer持有DataManager和一系列的Helper classe 。View Layer由Android的Framework組件組成,例如,Fragment,Activity,ViewGroup等。

Helper classes(圖標中的第三列)有着很是特殊的職責以及簡潔的實現方式。例如,不少項目須要一些幫助類對REST API進行訪問,從數據庫讀取數據,或者與三方SDK進行交互等。不一樣的應用擁有不一樣數量的幫助類,但也存在着一些共性:

  • PreferencesHelper:從SharedPreferences讀取和存儲數據。
  • DatabaseHelper:處理操做SQLite數據庫。
  • Retrofit services:執行訪問REST API,咱們如今使用Retrofit來代替Volley,由於它天生支持RxJava。並且也更好用。

幫助類裏面的大多數public方法都會返回RxJava的Observable。

DataManager是整個架構中的大腦。它普遍的使用了RxJava的操做符用來合併,過濾和轉換從幫助類中返回的數據。DataManager旨在減小Activity和Fragment的工做量,它們(譯者注:指Activity和Fragment)要作的就是展現已經準備好的數據而不須要再進行轉換了。

下面這段代碼展現了一個DataManager方法可能的樣子。這個簡單的示例方法以下:

  1. 調用Retrofit service從REST API加載一個博客文章列表
  2. 使用DatabaseHelper保存文章到本地數據庫,達到緩存的目的
  3. 篩選出今天發表的博客,由於那纔是View Layer想要展現的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Observable loadTodayPosts ( ) {
             return mRetrofitService . loadPosts ( )
                     . concatMap ( new Func1 , Observable > ( ) {
                         @ Override
                         public Observable call ( List apiPosts ) {
                             return mDatabaseHelper . savePosts ( apiPosts ) ;
                         }
                     } )
                     . filter ( new Func1 ( ) {
                         @ Override
                         public Boolean call ( Post post ) {
                             return isToday ( post . date ) ;
                         }
                     } ) ;
     }

View Layer中諸如Activity或者Fragment等組件只需調用這個方法,而後訂閱返回的Observable便可。一旦訂閱完成,經過Observable發送的不一樣博客,就可以當即被添加進Adapter從而展現到RecyclerView或其餘相似控件上。

這個架構的最後元素就是Event Bus(事件總線)。它容許咱們在Data Layer中發送事件,以便View Layer中的多個組件都可以訂閱到這些事件。好比DataManager中的退出登陸方法能夠發送一個事件,訂閱這個事件的多個Activity在接收到該事件後就可以更改它們的UI視圖,從而顯示一個登出狀態。

爲何這種架構更好?

  • RxJava的Observable和操做符避免了嵌套回調的出現。
 
  • DataManager接管了之前View Layer的部分職責。所以,它使Activity和Fragment變得更輕量了。
  • 將代碼從Activity和Fragment轉移到了DataManager和幫助類中,就意味着使寫單元測試變得更簡單。
  • 明確的職責分離和DataManager做爲惟一與Data Layer進行交互的點,使這個架構變得Test-Friendly。幫助類和DataManager可以很容易的被模擬出來。

咱們還存在什麼問題?

  • 對於龐大和複雜的項目來說,DataManager會變得很是的臃腫和難以維護。
  • 儘管View Layer諸如Activity和Fragment等組件變得更輕量,它們讓然要處理大量的邏輯,如管理RxJava的訂閱,解析錯誤等方面。

集成MVP

在過去的一年中,幾個架構設計模式,如MVP或者MVVM在Android社區內已經愈來愈受歡迎了。經過在示例工程文章中進行探索後,咱們發現MVP,可能給咱們現有的架構帶來很是價值的改進。由於當前咱們的架構已經被劃分爲兩個層(視圖層和數據層),添加MVP會更天然些。咱們只須要添加一個新的presenter層,而後將View中的部分代碼轉移到presenter就好了。

 

留下的Data Layer保持不變,只不過爲了與這種模式保持一致性,它如今被叫作Model

Presenter負責從Model中加載數據,而後當數據準備好以後調用View中相對應的方法。還負責訂閱DataManager返回的Observable。因此,他們還須要處理schedulerssubscriptions。此外,它們還能分析錯誤代碼或者在須要的狀況下爲數據流提供額外的操做。例如,若是咱們須要過濾一些數據並且這個相同的過濾器是不可能被重用在其餘地方的,這樣的話在Presenter中實現比在DataManager中或許更有意義。

下面你將看到在Presenter中一個public方法將是什麼樣子。這段代碼訂閱咱們在前一節中定義的dataManager.loadTodayPosts( )所返回的Observable。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void loadTodayPosts ( ) {
     mMvpView . showProgressIndicator ( true ) ;
     mSubscription = mDataManager . loadTodayPosts ( ) . toList ( )
             . observeOn ( AndroidSchedulers . mainThread ( ) )
             . subscribeOn ( Schedulers . io ( ) )
             . subscribe ( new Subscriber > ( ) {
                 @ Override
                 public void onCompleted ( ) {
                     mMvpView . showProgressIndicator ( false ) ;
                 }
 
                 @ Override
                 public void onError ( Throwable e ) {
                     mMvpView . showProgressIndicator ( false ) ;
                     mMvpView . showError ( ) ;
                 }
 
                 @ Override
                 public void onNext ( List postsList ) {
                     mMvpView . showPosts ( postsList ) ;
                 }
             } ) ;
     }

mMvpView是與Presenter一塊兒協助的View組件。一般狀況下是一個Activity,Fragment或者ViewGroup的實例。

像以前的架構,View Layer持有標準的Framework組件,如ViewGroup,Fragment或者Activity。最主要的不一樣在於這些組件再也不直接訂閱Observable。取而代之的是經過實現MvpView接口,而後提供一些列簡潔的方法函數,好比showError( )或者showProgressIndicator( )。這個View組件也負責處理用戶交互,如點擊事件和調用相應Presenter中的正確方法。例如,我有一個按鈕用來加載博客列表,Activity將會在點擊事件的監聽中調用presenter.loadTodayPosts( )

若是你想看到一個完整的運用MVP基本架構的工做示例,能夠從Github檢出咱們的Android Boilerplate project。也能夠從這裏閱讀關於它的更多信息Ribot的架構指導

爲何這種架構更好?

  • Activity和Fragment變得很是輕量。他們惟一的職責就是創建/更新UI和處理用戶事件。所以,他們變得更容易維護。
  • 如今咱們經過模擬View Layer能夠很容易的編寫出單元測試。以前這些代碼是View Layer的一部分,因此咱們很難對它進行單元測試。整個架構變得測試友好。
  • 若是DataManager變得臃腫,咱們能夠經過轉移一些代碼到Presenter來緩解這個問題。

咱們依然存在哪些問題?

  • 當代碼庫變得很是龐大和複雜時,單一的DataManager依然是一個問題。雖然咱們尚未走到這一步,但這是一個真正值得注意的問題,咱們已經意識到了這一點,它可能發生。

值得一提的是它並非一個完美的架構。事實上,不要天真的認爲這是一個獨特且完美的方案,可以解決你全部的問題。Android生態系統將保持快速發展的步伐,咱們必須繼續探索。不斷地閱讀和嘗試,這樣咱們才能找到更好的方法來繼續構建優秀的Android應用程序。

最後多實踐,發現祕密。

adiOS

相關文章
相關標籤/搜索