Android 組件化實現
一、介紹
將一個app分成多個模塊,每個模塊都是一個組件(Module),開發的過程中我們可以讓這些組件相互依賴或者單獨調試部分組件等,但是最終發佈的時候是將這些組件合併統一成一個apk,這就是組件化開發。組件化開發中認爲組件作爲系統的一部分,是可獨立運行的服務。
優點:一個複雜的系統由一個個組件集合而成,不同的組合可以構建出不同的系統。每個組件有獨立的版本,可獨立編譯、打包,大大提高了系統的靈活性以及開發人員的開發效率。應用的更新可以精細到組件,組件的升級替換不會影響到其它組件,也不會受其它組件的限制。
缺點:組件化的實施對開發人員和團隊管理人員提出了更高水平的要求,項目管理難度更大。組件間如何進行通信也是需要慎重考慮的。萬事開頭難,在對一個項目進行組件化分解時就好像庖丁解牛一般,你需要了解項目的“肌理筋骨”,才知道從何處下“刀”,才能更輕易的去分解項目,這就要求架構師對於項目的整體需求瞭如指掌。
組件可以分爲業務組件和功能組件,功能組件爲業務組件的運行提供功能支持。
二、實現細節
1.組件模式和繼承模式轉化
Android studio中Module有兩種形式(Application和Library)
1.application屬性是可以獨立運行的程序
apply plugin: ‘com.android.application’
2.library屬性,不可以獨立運行,一般是Android程序依賴的庫文件
apply plugin: ‘com.android.application’
該屬性是在每個Module的build.gradle文件配置的,組件模式開發時,業務組件應該爲application屬性,每個業務組件可以獨立開發和調試;集成模式開發時業務組件應該爲library屬性,作爲一個依賴包導入到殼工程。
如何讓組件在組件模式和集成模式轉變呢?總不可能每次都修改gradle文件吧,業務組件少一點還可以忍受,一旦項目變大,業務組件多達十幾個的時候,手動改一遍必定費時費力。解決辦法是在gradle.properties文件中添加一個isModule常量(true爲組件式開發,false爲集成式開發),因爲在Android項目中的任何一個build.gradle文件中都可以把gradle.properties中的常量讀取出來,我們可以通過讀取這個常量的值來判斷開發模式。
//在gradle.properties文件中添加下列字段
isModule=false
在每個業務組件的build.gradle文件開頭添加下列字段
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
在殼工程的build.gradle文件的dependencies中添加下列字段
if (!isModule.toBoolean()){
implementation project(':chat')
}
2.統一管理版本號和引入包
1.在Project目錄下創建config.gradle,並且在Project目錄下的build.gradle中引入:
ext {
def versions = [:]
versions.support = "29.0.2"
android = [
applicationId : "com.wjxk.cardbutler",
compileSdkVersion: 29,
minSdkVersion : 21,
targetSdkVersion : 29,
versionCode : 1,
versionName : "1.0.0",
]
dependencies = [
glide : 'com.github.bumptech.glide:glide:4.6.0',
rxJava : "io.reactivex.rxjava2:rxjava:2.2.3",
rxAndroid : "io.reactivex.rxjava2:rxandroid:2.1.0",
okhttploggingintercepter: "com.squareup.okhttp3:logging-interceptor:3.5.0",
retrofit : "com.squareup.retrofit2:retrofit:2.4.0",
retrofit_gson : "com.squareup.retrofit2:converter-gson:2.4.0",
retrofit_rxJava_adapter : "com.squareup.retrofit2:adapter-rxjava2:2.3.0",
]
support = [
constraintlayout: 'androidx.constraintlayout:constraintlayout:1.1.3',
appcompat : 'androidx.appcompat:appcompat:1.0.2',
]
}
在主工程的build.gradle文件開頭添加下列代碼
apply from: 'config.gradle'
然後在將各個組件裏的build.gradle中的版本號改成下列代碼(以下僅是部代碼,第三方依賴包也要改動)
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
3.組件之間AndroidManifest合併問題
在 AndroidStudio 中每一個組件都會有對應的 AndroidManifest.xml,用於聲明需要的權限、Application、Activity、Service、Broadcast等,當項目處於組件模式時,業務組件的 AndroidManifest.xml 應該具有一個 Android APP 所具有的的所有屬性,尤其是聲明 Application 和要 launch的Activity,但是當項目處於集成模式的時候,每一個業務組件的 AndroidManifest.xml 都要合併到“app殼工程”中,要是每一個業務組件都有自己的 Application 和 launch的Activity,那麼合併的時候肯定會衝突,試想一個APP怎麼可能會有多個 Application 和 launch 的Activity呢?
爲組件開發模式下的業務組件再創建一個 AndroidManifest.xml,然後根據isModule指定AndroidManifest.xml的文件路徑,讓業務組件在集成模式和組件模式下使用不同的AndroidManifest.xml,這樣表單衝突的問題就可以規避了。
在每個業務組件的build.gradle文件的android模塊添加下列代碼
sourceSets {
main {
if (isModule.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
4.組件間通信
在組件化開發的時候,組件之間是沒有依賴關係,我們不能在使用顯示調用來跳轉頁面了,因爲我們組件化的目的之一就是解決模塊間的強依賴問題,假如現在要從A業務組件跳轉到業務B組件,並且要攜帶參數跳轉,這時候怎麼辦呢?而且組件這麼多怎麼管理也是個問題,這時候就需要引入“路由”的概念了,由本文開始的組件化模型下的業務關係圖可知路由就是起到一個轉發的作用。
這裏我介紹一個阿里開源的路由框架ARouter,具體用法自行百度,下一遍文章我會自己手寫一個組件間通信的新方案,通過接口下沉的方式實現組件間通信。