1. 程式人生 > >一種Android分包策略推薦

一種Android分包策略推薦

簡單 重要性 xxx ava 經驗 music androi news 開源

分包的重要性

在架構一個App時,大家往往都在關註新潮的技術,卻忽略了一點,那就是分包。很多人可能沒有一套分包的原則,憑感覺甚至隨心所欲地創建package或將代碼放到任意的package中。

雖然最終不會影響App功能,但這個問題其實非常嚴重。一種不好的分包策略帶來的影響將會一直持續在App的開發叠代周期中,主要表現為以下幾點:

  1. 代碼混亂,功能模塊界限模糊
  2. 不易閱讀與維護,尤其對新人來說
  3. 功能擴展與重用困難
  4. 包間耦合比較高

根據個人多年App開發經驗及項目實踐,現推薦一種Android分包策略,雖並非最優,但基本適合絕大多數的android應用開發。

一種分包策略

反例分析

先來看一個“反例”(已加引號,如此分包者輕拍)。曾見過一些第三方項目或開源項目,它們的分包策略是這樣的:

  1. 把應用中所有的Activity放到一個包中,如com.example.activities
  2. 把應用中所有的Fragment放到另一個包中,如com.example.fragments
  3. ……

相信有相當一部分開發者是這樣分包的,來分析下其優缺點。

優點呢?或許說分類特別清晰,如所有的Activity都在一起,但是仔細想想,這樣又有什麽意義呢?

缺點卻非常明顯:

  1. 當看到這樣的一個App分包結構時,大家可能都不知道該App有哪些功能、應用入口在哪裏
  2. 代碼混亂,雜糅在一起,沒有清晰的模塊界限
  3. 可讀性差,查找一個功能頁面時,可能需要跨多個包才能找到
  4. 修改維護則更加麻煩,根本不知道某個類是否在其他包中使用
  5. ……

分包原則

分包並沒有官方原則,因此是自由的,但完全自由等於沒有自由。

先拋出個人推薦的分包原則:按功能模塊分包。

這樣說有點抽象,我們細化到一個App示例中去,假設一個App具有如下功能:

基礎支持功能

  1. 網絡請求
  2. 圖片處理
  3. 數據庫
  4. ……

業務功能

  1. 新聞相關功能模塊
  2. 電影相關功能模塊
  3. 音樂相關功能模塊
  4. ……

對於以上示例App,我們按照功能模塊來分包:

  1. 將網絡功能相關代碼歸到一個包,如com.example.network,至於具體用OkHttp還是Volley或者自己封裝HttpURLConnection都無所謂。
  2. 將圖片加載、縮放、緩存等相關功能代碼歸到一個包,如com.example.image,同樣跟使用哪種圖片框架無關。
  3. 將Sqlite數據庫相關操作的代碼歸到一個包,如com.example.db。
  4. 將新聞功能模塊的相關業務代碼歸到一個包,如com.example.news,同時新聞功能相關的所有Activity和Fragment都放到這個包中。
  5. 將電影功能模塊的相關業務代碼歸到一個包,如com.example.movie,同時電影功能相關的所有Activity和Fragment都放到這個包中。
  6. 將音樂功能模塊的相關業務代碼歸到一個包,如com.example.music,同時音樂功能相關的所有Activity和Fragment都放到這個包中。
  7. 對於adapter,如是封裝的通用的adapter,則可歸到com.example.adapter中,如僅僅是某個Activity自己用的adapter,也可放到業務模塊的包中,這裏推薦所有adapter放到一個獨立的包中,因為我們查找代碼時,往往從功能模塊角度入口,根據功能分包原則,可以快速找到對應包中的Activity,找到了Activity,其用到的adapter、entity便也可以迅速找到,因此不必也放到功能模塊的包中。
  8. 對於自定義控件,可以統一歸到一個包,如com.example.widget。
  9. 對於某些基類,如BaseActivity和BaseFragment等可以放到一個叫com.example.base的包中。
  10. 對於數據對象實體,可統一放到com.example.entity中,不要放到具體功能模塊的包中,原因第7點已提及,另外實體還可能重用、繼承等。
  11. 對於業務無關的公用方法和工具類,可以放到com.example.util中。
  12. ……

基於上述分包策略,在Android Studio中一個App的層次結構示意圖如下:

           java
           |--- com
                |---example
                    |--- base
                    |    |--- BaseActivity.java
                    |    |--- BaseFragment.java
                    |    |--- xxx.java
                    |
                    |--- network
                    |    |--- HttpClient.java
                    |    |--- xxx.java
                    |
                    |--- image
                    |    |--- ImageManager.java
                    |    |--- xxx.java
                    |
                    |--- db
                    |    |--- DbManager.java
                    |    |--- xxx.java
                    |
                    |--- news
                    |    |--- NewsActivity.java
                    |    |--- NewsFragment.java
                    |    |--- xxx.java
                    |
                    |--- movie
                    |    |--- MovieActivity.java
                    |    |--- MovieFragment.java
                    |    |--- xxx.java
                    |
                    |--- music
                    |    |--- MusicActivity.java
                    |    |--- MusicFragment.java
                    |    |--- xxx.java
                    |
                    |--- entity
                    |    |--- Movie.java
                    |    |--- News.java
                    |    |--- xxx.java
                    |
                    |--- adapter
                    |    |--- AbsAdapter.java
                    |    |--- MovieAdapter.java
                    |
                    |--- widget
                    |    |--- CircleImageView.java
                    |    |--- xxx.java
                    |    
                    |--- util
                         |--- ToastUtil.java
                         |--- xxx.java
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

優點

使用上述分包策略後,主要優點如下:

  1. 從分包結構就能大概了解該App的功能
  2. 高度模塊化,可讀性及可維護性大大提升
  3. 功能模塊導航清晰,很容易查找相關功能代碼,哪怕是新人也能快速找到對應代碼
  4. 包與包之間的耦合性降低,添加或刪除功能模塊變得簡單
  5. 修改代碼時,一般僅涉及某個功能,一般不用擔心影響到其他包中的功能實現
  6. 更加抽象化、模塊化,方便擴展和重用,尤其是基礎功能模塊
  7. 從代碼訪問權限角度來看,包內調用權限可替代包間調用,安全性也會提高

總結

分包本身就是一個開放性的問題,沒有固定或最優的方案,上面推薦的策略也只是一些基本原則,具體細節可根據App實際情況制定,歡迎探討。

一種Android分包策略推薦