前言
至今為止從事Android開發兩年多了,17年開始實習時,恰逢APP剛剛立項不久,當時新項目沿用了舊項目古老的MVC架構。從那之后一直都是根據飄忽不定的需求,沒有規則的壘代碼。
直到18年中,其他項目組開發的APP要求集成到了我們項目組的APP中,從這時開始項目的代碼、APP的功能,爆炸性增多,代碼本身也開始變得極難維護,調試舊代碼經常找不到位置,需要全局搜索有時還要連蒙帶猜,也就是從那時起,我開始意識到一個好架構以及規范的重要性!
目錄
- 項目簡介
- APP概覽
- 項目結構
- 組件復用
- 后續展望
- 總結
- 參考資料
正文
一、項目簡介
本次實踐的內容是基于Android JetPack組件實現MVVM架構,并結合當下較為流行的組件化開發方式,編寫的一個菜譜類型的小型應用。組件化的過程中結合了我把公司的APP組件化后,得到一些經驗和教訓,做了一些優化和調整。
需要強調的是,實際使用了Data Binding后,不僅調試bug時想砸電腦,后來在讀過nanchen大佬的文章《不一樣的角度談 DataBinding的坑》后決定,在本次實踐暫不采用Data Binding,后續會單獨開設分支來實現DataBinding。
項目當前的MVVM架構設計的可能并不理想,而且界面優化還存在一定的問題,不過沒關系,后續會以該項目為案例,系統性的實踐Android中常見的啟動優化、內存優化以及布局優化等等,實踐過程也會完整的整理成文章記錄下來,方便日后學習、討論,如果感興趣話記得關注哦。
后臺服務器:Bmob(使用了bmob用戶管理的部分api,其他數據主要使用easy-mock產生模擬數據)
開發語言:Kotlin(部分使用了Java)
主要使用的Jetpack組件:
LiveData-Android Architecture Components探索(1)-LiveData
ViewModel-Android Architecture Components探索(2)-ViewModel
Navigation-Android Architecture Components探索(3)-Navigation
Room、Lifecycle
使用到的第三方框架:App中使用了很多第三方框架,這里只列舉幾種,Tinker(熱修復)、ARouter、Glide、RxJava、Retrofit、BaseRecyclerViewAdapterHelper、X5WebView等等。
開源地址:https://github.com/linux-link/Fan
二、APP概覽
三、項目結構
本項目概念上的結構如圖所示
實際結構如圖所示
下面分別解釋各個module的作用:
-
Library-Base
整個項目的基類,所有的第三方框架和自定義View框架都在這里添加依賴,以方便統一管理。
-
View_Xxx
通用的自定義View框架。一些APP特有的view效果可以抽出獨立成一個Module。例如:本項目使用了一個仿紅板報的3D翻頁效果庫,就可以把它獨立成一個module。
-
General_Xxx
通用的自定義工具框架。一些所有項目可以公用的框架,為了方便日后在其他項目中使用,可以抽出獨立成一個module,不能與項目的業務邏輯有關聯。例如:本項目中網絡框架就被單獨封裝成一個module。
-
Library-Architecture
通用框架庫。一般包含BaseApplication、常用的工具類以及架構層的封裝例如BaseMvvmActivity等等。
這個module在封裝時需要考慮一定的通用性,最理想的情況的是,在重新開一個新的項目時,可以直接拷貝使用。
-
Library-Component
服務于組件化的module。與業務邏輯相關,主要包含一些組件化的封裝,一些子組件需要抽出的公共類也會放在這里。需要注意的是,Library-Component是其他所有子組件必需依賴的庫。
-
Component_Xxx
子組件。APP中各個業務邏輯的具體實現,既可以編譯為library,用作其他組件的類庫,也可以編譯為application,可以獨立運行調試。
在項目根目錄的build.gradle可以通過xxx_isSingleCompile的值來控制各個module是否需要獨立運行。
-
app
整個項目的入口,又被成為APP殼,在這里面將所有的子組件全部打包進apk中,為了加快編譯速度,主要使用runtimeOnly。
需要單獨說明的是,每一個子組件中還包含了一個gradle.properties文件,里面設定了該組件被編譯成AAR庫時一些屬性,以及私有maven倉庫的地址和用戶名與密碼。
四、組件復用(2019-08-22 更新)
組件化的一個重要目的就是能夠在另一個項目中復用當前APP的一些組件,就像我們在項目中使用implementation引入一些第三方庫一樣,這些第三方庫也可以當作一個組件。不過為了隱私的需要,我們多數時候是在公司的內網使用nexus搭建一個私有的maven倉庫。
關于如何搭建maven倉庫就不再介紹了,請自行百度,這里我在華為云服務器上搭建了一個公用的maven倉庫(自行搭建maven倉庫時,盡量使用內存大于2GB的主機),公網地址:http://119.3.215.243:9882,用戶名:public,密碼:123456@qq.com。
有了maven倉庫,接下來我們就可以嘗試將組件打包并上傳到maven倉庫中,給別項目使用。
1.編譯aar類庫并上傳maven倉庫
-
選擇一個module,執行build命令,將這個module編譯成一個aar類庫。編譯好的aar文件,一般在對應module的build->outputs->aar下
執行腳本 -
在gradle.properties中配置maven倉庫地址,以及組件的其他屬性
配置屬性 -
執行upload腳本,將aar類庫上傳到maven倉庫中
上傳到maven倉庫
控制臺出現successful,表示上傳成功
接下來就是如何在當前項目或其他項目中使用這個aar的類庫
2.使用aar類庫
-
在根部目錄的version.gradle中添加私有maven倉庫的地址
引入私有maven倉庫的地址 -
使用在gradle.properties配置的唯一項目標識,引入aar類庫
統一配置aar類庫的地址
修改引入類庫的地址 -
在setting.gradle中,把一些已經編譯成aar類庫module注釋掉
注釋掉源碼形式的module
通過以上這些步驟,我們實現了組件的本地復用以及不同項目間的復用,而且因為大量的組件被編譯成了aar類庫,項目全編譯時,這部分組件就不需要再進行編譯,大幅提高了項目的編譯效率。
五、后續展望
當前的APP依然十分簡單,或者說簡陋,當前正在學習如何部署、開發一個簡單的后臺,后面會逐漸放棄bmob,同時增加APP的復雜度,引入更多的開發技術,比如我最感興趣的插件化、NDK、React Native或者Flutter等等。
最終目的還是希望能在一個APP中實踐當下的主流開發技術,然后從中選擇一個方向深入研究,不過這都是后話了。畢竟理想很豐滿,現實很骨干=_=。
更新內容
2019-08-22更新
- 1.0.3版開始,在APP中集成了一個獨立進程的簡易商城,商城使用H5開發,支付功能使用Native開發,商城本質上是一個多進程Hybird架構的組件。
H5部分是根據慕課網的一個vue.js課程中使用的源碼改造的,所以源代碼無法公開。不過我同樣架設了一個可以在公網訪問的地址:http://118.24.197.176,因為數據需要使用APP的內置網絡服務獲取,所以在瀏覽器中訪問這個地址是缺失部分數據的。
2019-08-23更新
- 1.0.4版集成了美團walle多渠道打包,實際開發中打出不同的渠道包,網絡請求時帶上渠道標識,這可以方便后臺對于APP的統計。
在需要渠道等信息時可以通過下面代碼進行獲取
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
使用./gradlew clean assembleReleaseChannels指令生成渠道包,渠道包的生成目錄默認存放在 build/outputs/apk/,也可以通過walle閉包中的apkOutputFolder參數來指定輸出目錄。
2019-08-27更新
- 新增一個以glide為基礎,運用策略、單例、建造模式封裝的一個可以在使用時靈活切換(例如從glide切換為picasso)的圖片載入框架general_picture,目前依然在優化中,暫時可以正常使用。
實際開發中方圖片載入框架需要足夠的靈活,否則一但需要切換圖片加載框架,絕對會非常麻煩。
六、總結
以上就是本項目的大致概覽,總得來說,你既可以用它來學習組件化開發,也可以用它來學習Android Jetpack組件的實際運用,還可以用來學習如何優化一個APP,不過這等我后續的更新了,當前已經更新的有
如有任何問題、建議請給我留言或者在github中提交issue。感謝您的閱讀,歡迎下載體驗。