完整的Android MVP開發之旅_Android

來源:互聯網
上載者:User

開發背景
最近是在做一個與健身相關的APP,裡面有訓練器模組準系統是按照特點動作的示範和描述來引導使用者完成訓練。在第一個版本時由於沒接觸過些類項目與功能花了幾周的時間大概1500行代碼才完成這個功能,
當時雖然我已經盡量讓代碼錶現的清晰,但是可以想像到當一個Activity中包含這麼多代碼是什麼感覺。自己維護起來都難受。

先談設計
有了前設計一次經驗此次開發使用MVP、模組化、面向介面等概念,將整個訓練器分為控制器、資料模型、音頻、視圖、可訓練對象五個模組分別用以下介面表示:

  • ITrainerController
  • ITrainerModel
  • IAudioFlow
  • ITrainerView
  • ITrainable

去掉一些抽象類別後介面圖如下:

設計以上介面後引入MVP概念使用ITrainerController做為Presenter,ITrainerModel做Model,ITrainerView做View下面介紹主要模組。

控制器
可以用在MVC和MVP中這取決於用哪種開發模式,在我開發的項目控制器用來控制訓練器的運行管理訓練器的生命週期如訓練、暫停、休息、完成等狀態協調ITrainerModel、ITrainerView、IAudioFlow等各個模組。
在使用過程中控制器並不止一個這也是抽象出一個介面的原因,ITrainerController介面繼承IPresenter介面使其能做為Presenter使用。

資料模型
資料模型中包含大量的ITrainable對象,對內組織資料對外提供資料支援。對資料的組織方式主要分兩種:

  • 從本機資料庫
  • 從網路擷取

在訓練器中可能是正常的訓練或是一次訓練測試而訓練資料和測試資料又有一些差異但它們的資料都被當做ITrainable,測試資料是不需要儲存的只需要從伺服器拉取後按要求完成就行而訓練是會產生本地記錄的。
針對不同資料群組織方式提供不同的資料模型這是有必要的。

音頻
音頻比較多樣化像訓練過程中包含動作名、時間、單位詞、提醒等音頻這些音頻都是分開的不同的音頻檔案。Android主要有兩種實現方式:

  • SoundPool
  • MediaPlayer

首先說SoundPool優點自然就是免去了載入、管理音頻等過程但是它並不適應我們的訓練器,主要原因是缺少準備、完成後的一些回調而在訓練器運行過程中這些過程必不可少比如在播放完一段預備開始後音頻這時我們才能進行正式的訓練。
最後是採用MediaPlayer,但是在使用過程又要考慮到音訊集中管理與資源的釋放免不了多封裝一次。設計時我將全部音頻邏輯放在Android Service中Activity通過bind AudioService來使用音頻,將音頻邏輯放入AudioService這樣可以音頻完
全獨立起來使其能在背景播放並且也可以提高進程優先順序。

在設計中AudioService僅僅播放與管理音頻和資源並不具備音頻播放的邏輯功能。由於不同的訓練方式音訊播放邏輯也有不同之處所以在此設計IAudioFlow介面來負責音頻邏輯。

訓練視圖
Android常用Activity作為視圖,通過實現ITrainerView介面來完成訓練視圖的顯示。視圖中不包含任何商務邏輯代碼。

再談實現
說到實現其實這並不是最需要關注的內容,因為上面提供了很全面的介面而我們的模組又是使用的介面所以不管如何?那些功能並不會對各個模組之間產生大的影響除非功能實現與實際要求相差太多。這裡我只詳細說一下音頻模組的實現。

音頻實現
音頻模組又可分為音頻管理與音頻商務邏輯。音頻管理就是載入、播放、回收資源等功能,音頻商務邏輯主要處理在正確的狀態下應該播放什麼樣的音頻。將整個音頻管理模組放在Android Service中與商務邏輯完全分離。音頻模組涉及以下類與介面:

  • AudioService: 音頻伺服器繼承Android Service
  • IAudioService: 音頻抽象介面包含播放、暫停等事件
  • MediaPlayerHolder: 持有MediaPlayer管理MediaPlayer生命同期
  • IAudioFlow: 為不同的訓練內容提供音頻邏輯
  • AudioServiceImpl: 實現IAudioService

基本使用流程是首先通過綁定AudioService的onBind方法返回IAudioService的實作類別供IAudioFlow使用,IAudioFlow持有IAudioService實現後載入訓練音頻然後供ITrainerController使用。在AudioServiceImpl中會維持一個音頻最佳化級隊列,
上面提到因為音頻都是不在一個檔案中的所有需要在使用時將它們串連起來形成一段音頻。通過優先順序隊列結合MediaPlayer播放完成時回調可以將多個音頻組合在一起形成需要的音頻。由於音訊播放越來越多MediaPlayer的回收利用特別重
要在AudioServiceImpl同樣也具備MediaPlayer的回收與利用功能。這個功能實現是通過MediaPlayerHolder來處理的,通過MediaPlayerHolder的靜態get方法擷取MediaPlayerHolder如果回收池中有閒置MediaPlayerHolder則拿來用沒有時則
建立一個,同樣也在一個音頻播放完成後調用MediaPlayerHolder的recycle來進行回收利用。

模組整合
為減少相依模組之間的整合需提供管理或協助類,建立TrainerHelper來建立模組實作類別其中包含一個Mode枚舉來列舉訓練模式。

public class TrainerHelper {  public enum Mode{TEST, TRAINING, EXAM}  private static Mode mode;  public static void setMode(Mode m){    mode = m;  }  public static ITrainerController createPresenter(ITrainerView view, Bundle createArgs){    return new TrainerPresenter(view,createArgs);  }  public static ITrainerModel createTrainerModel(ITrainerController controller){    return = new DefaultTrainerModel(bundle);;  }  public static IAudioFlow createTrainerAudioFlow(ITrainerController controller){    return new DefaultAudioFlow(controller);  }}

總結
成功的設計與架構能減少大量的工作時間,利用介面可讓開發人員更加註重功能上的實現同時隔離各個模組之間的依賴。下次產品經理再改需求或再整出個訓練模式時咱也能從容應對。

由於本人水平有限如有錯誤,請大家諒解。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.