從零開始搭建架構實施Android專案

LeoLiang發表於2016-01-12

我們先假設一個場景需求:剛有孩子的爸爸媽媽對用照片、視訊記錄寶寶成長有強烈的意願,但苦於目前沒有一款專門的手機APP做這件事。A公司洞察到市場需求,要求開發團隊儘快完成Android客戶端的開發。以下模擬團隊和工作開展。

  • 團隊情況:產品經理1人,Android開發2人,服務端開發2人,UI設計1人。
  • 開發週期:兩個月。
  • 工作量:大約50個介面。
  • 隱含需求:考慮到使用者群體有可能激增的情況,服務端需要有一定的併發能力。
  • 前提:原型已設計完成。

1 服務端概要設計

1.1 系統架構

先給出服務端的架構圖。

由於服務端開發有Java、PHP背景,為了快速完成開發任務,我們選擇PHP作為服務端開發語言,順便也把資料庫定為MySQL。考慮後期擴充套件和資料庫訪問效能,擬引入Redis非關係型資料庫。同時為了提高資料讀的效能,在雲伺服器和資料庫之間用上快取,併為資料庫主從備份、讀寫分離。伺服器就不搭建在本地了,管理是一大問題。現在雲伺服器一大把,七牛、阿里雲、騰訊雲、百度雲、金山雲等等,技術成熟,而且價格還算公道。在此我們選擇阿里雲。為了應對可能面臨的併發問題,雲伺服器要考慮負載均衡。專案中可能存在大量的需要上傳和下載照片和視訊,我們選擇阿里雲的開放儲存服務,同時為了提升各個地區的下載體驗,我們引入CDN。客戶端通過API Service和服務端交換資料,圖片和視訊的下載直接通過CDN。

1.2 模組劃分

根據需求和原型設計,可能的模組劃分如下:

  • 註冊登入模組
  • 使用者模組
  • 小孩模組
  • 媒體(圖片+視訊)模組
  • 相簿模組
  • ……

1.3 資料交換和API介面

服務端與客戶端使用JSON交換資料,使用自定義JSON格式,約定返回code、message,實體封裝在result中,支援單個實體、實體列表、多個實體列表,定義如下:

主要API介面設計如下:

也許你看到了,API做了二級域名對映,同時為了服務端後期API版本的升級管理,在URL中加上了版本標識V1.0。命名方面我儘量做到restful的風格。對了,此處沒有使用Https。為了解決資料傳輸的安全,我做了點特別的處理:對請求體和響應結果進行RSA加密(如果服務端返回的資料稍稍過大,這個RSA嚴重影響客戶端解密,後來我換成了AES),所有請求為POST請求,所以API URL後面沒有帶引數,你也看不到任何請求相關的資訊。

1.4 資料庫設計

根據需求和原型設計,資料庫的設計大概需要兩週時間。其實一週基本搞定了,但為了考慮充分,留出一週時間來檢驗和調整。資料庫E-R圖略。

2 Android客戶端

2.1 基本結構

Android本身就是MVC,所以我不打算引入MVPMVVM。我的理念是職責分層,快速推出Android 1.0。主要的包結構如下:

工程的搭建和包的劃分有各種各樣的,適合自己的就行了。想討論或想看別人怎麼做的,點選這裡:App工程結構搭建:幾種常見Android程式碼架構分析

2.2 功能劃分

註冊登入,個人資訊,我的小孩,相簿管理,訊息通知,系統設定等等。

2.3 引入的第三方技術

重複發明輪子是不可取的。有些模組根本沒必要自己寫。以下是引入的第三方庫,以及優勢說明。

2.3.1 網路請求庫android-async-http

  • 在匿名回撥中處理請求結果
  • 在UI執行緒外進行http請求
  • 檔案斷點上傳
  • 智慧重試
  • 預設gzip壓縮
  • 支援解析成Json格式
  • 可將Cookies持久化到SharedPreferences

2.3.2 雲巴推送

  • 專注於為需要實時資料交換的產品提供完美解決方案
  • 基於釋出者/訂閱者(publisher/subscriber)模式,整合簡單
  • 對比了百度雲推送、騰訊信鴿推送,雲巴效果更好
  • 原極光推送CTO創辦的

2.3.3 xUtils(只使用其中的DbUtils和ViewUtils)

  • Android中的ORM框架,一行程式碼就可以進行增刪改查
  • 支援事務,預設關閉
  • 可通過註解自定義表名、列名、外來鍵、唯一性約束、NOT NULL約束、CHECK約束等(需要混淆的時候請註解表名和列名)
  • Android中的IOC框架,完全註解方式就可以進行UI,資源和事件繫結
  • 新的事件繫結方式,使用混淆工具混淆後仍可正常工作

2.3.4 友盟統計

  • 國內專業的移動應用統計分析平臺
  • 統計和分析流量來源、內容使用、使用者屬性和行為資料
  • Crash log跟蹤

2.3.5 雲通訊驗證碼

  • 解決方案成熟,眾多公司使用

2.3.6 高德地圖定位

  • GPS+基站+wifi的混合定位方式
  • 接入簡單

2.3.7 非同步圖片載入庫Android-Universal-Image-Loader

  • 多執行緒下載圖片,圖片可以來源於網路,檔案系統,專案資料夾assets中以及drawable中等
  • 支援隨意的配置ImageLoader,例如執行緒池,圖片下載器,記憶體快取策略,硬碟快取策略,圖片顯示選項以及其他的一些配置
  • 支援圖片的記憶體快取,檔案系統快取或者SD卡快取
  • 支援圖片下載過程的監聽
  • 根據控制元件(ImageView)的大小對Bitmap進行裁剪,減少Bitmap佔用過多的記憶體
  • 較好的控制圖片的載入過程,例如暫停圖片載入,重新開始載入圖片,一般使用在ListView,GridView中,滑動過程中暫停載入圖片,停止滑動的時候去載入圖片
  • 提供在較慢的網路下對圖片進行載入

2.3.8 阿里雲OSS Android客戶端SDK

  • 提供檔案(圖片、視訊等等)上傳
  • 大檔案分塊上傳
  • 刪除操作(不推薦在客戶端使用)

2.3.9 元件內通訊EventBus

  • 基於釋出者/訂閱者(publisher/subscriber)模式
  • 簡化了應用程式內各元件間、元件與後臺執行緒間的通訊

2.3.10 Android本地資料庫加密庫SQLCipher

  • 基於SQLite擴充套件的開源資料庫,在SQLite的基礎之上增加了資料加密功能
  • SQLCipher對Android SDK中所有與資料庫相關的API都製作了一份映象,使得開發者可以像操作普遍的資料庫檔案一樣來操作SQLCipher

2.4 基礎元件封裝

2.4.1 基礎回撥介面

2.4.2 網路訪問

先看一下登入的序列圖:

HttpManager類負責呼叫AsyncHttpWrapper中的post方法,和對服務端返回的資料解密、JSON轉物件、回撥上層;AsyncHttpWrapper則負責請求體的封裝加密和其它的校驗引數封裝。看一下HttpManager類的post方法:

AsyncHttpWrapper中的post方法

2.4.3 Adapter封裝

為了加快開發速度,重用程式碼,Adapter的使用有技巧。每次在getView中查詢控制元件id、利用ViewHolder、賦值,最後返回convertView,看著都是差不多的程式碼。是時候脫離這個苦海了。先看怎麼解決共用的ViewHolder問題。

ViewHolder的作用,就是通過convertView.setTag與convertView進行繫結。當convertView複用時,直接從與之對應的ViewHolder(getTag)中拿到convertView佈局中的控制元件,省去了findViewById的時間。上面的程式碼就是這樣的原理。

然後就是CommonAdapter了。

好了,不貼程式碼了。看不明白了請點選這裡:Android 快速開發系列 打造萬能的ListView GridView 介面卡

 

2.4.5 其它Utils封裝

如AES128加密類、BitmapUtils、SecurePreferences、StringUtil、ToastUtil、IOUtil等等。

 

2.5 介面測試

為了保證資料交換、加解密正常,首先對某一個介面進行測試,以驗證API Service能正常跑通。比如可以先對登入進行模擬測試,看是否成功,同時包括異常的測試,服務端是不是處理了邊界異常,返回給客戶端的都是封裝過的異常資訊,而不是拋一個敏感資訊給客戶端。提前進行介面測試有助於我們的基礎元件執行沒問題,方便後期其它模組的快速整合。

 

2.6 快速開發

基礎元件封裝好後,除了少量的從網路獲取資料邏輯和本地資料庫的增刪改查,客戶端基本上就是介面的佈局工作了。介面開發基本看熟練程度和自定義View的重用。

好了,基本就這些。兩個Android開發人員兩個月內完成肯定是可以的,前提是至少有一個熟手。後面再談談MVP,畢竟這個客戶端設計沒法進行單元測試,如果業務邏輯越來越複雜,Activity的職責會越來越重,問題多多,不利於後期維護。

相關文章