一、背景
一個app隨著業(yè)務(wù)增加驾孔,代碼放在同一個模塊中會越來越臃腫芍秆,同時也導(dǎo)致多人開發(fā)的一個難度惯疙。組件化可以把業(yè)務(wù)單獨分出來,形成一個單獨模塊妖啥,可單獨運行霉颠、測試等,相互之間不會影響荆虱。另外一個優(yōu)勢掉分,如果一個公司有多個app,總會出現(xiàn)一些相同業(yè)務(wù)克伊,如登錄/注冊酥郭。我們可以單獨把公共業(yè)務(wù)封裝成一個單獨模塊,供所以app使用愿吹,提高了開發(fā)成本
二不从、項目結(jié)構(gòu)
如下圖1,項目分成了4層犁跪,第一層app殼椿息,這個也就是我們主工程, 里面包含application,啟動頁坷衍,以及一些初始化操作寝优。第二層為module層,也就是我們的具體業(yè)務(wù)模塊枫耳,具體需要看業(yè)務(wù)乏矾。第三層公共資源庫,所有module都依賴此lib庫迁杨。第四層為工具層钻心,我們可以封裝一些常用的網(wǎng)絡(luò)請求,圖片框架等
圖1
三铅协、組件開發(fā)代碼配置
-
先給大家看下工程主要目錄結(jié)構(gòu) 圖2
在project目錄下創(chuàng)建一個全局的config.gradle配置文件捷沸。具體每個字段作用,看代碼注釋狐史,這里就不作講解了
ext{
//組件獨立調(diào)試開關(guān), 每次更改值后要同步工程
isDebug = false
//統(tǒng)一管理Android配置
android = [
// 編譯 SDK 版本
compileSdkVersion: 32,
// 最低兼容 Android 版本
minSdkVersion: 22,
// 最高兼容 Android 版本
targetSdkVersion: 31,
// 當前版本編號
versionCode: 1,
// 當前版本信息
versionName: "1.0.0"
]
//組件唯一包名
applicationid = [
"app":"com.example.demo",
"lgoin":"com.test.login",
]
//請求測試服/正式服
url = [
"debug": "http://v.juhe.cn",
"release":"http://v.juhe.cn"
]
//統(tǒng)一管理module的第三方依賴
dependencies = [
corektx: 'androidx.core:core-ktx:1.7.0',
appcompat: 'androidx.appcompat:appcompat:1.3.0',
material: 'com.google.android.material:material:1.4.0',
constraintlayout: 'androidx.constraintlayout:constraintlayout:2.0.4',
junit: 'junit:junit:4.13.2',
junittest: 'androidx.test.ext:junit:1.1.3',
espressocore: 'androidx.test.espresso:espresso-core:3.4.0',
]
//路由
libARouter= 'com.alibaba:arouter-api:1.5.2'
libARouterCompiler = 'com.alibaba:arouter-compiler:1.5.2'
//Gson解析
libGson = 'com.google.code.gson:gson:2.8.9'
}
- 引入config.gradle配置文件,在project全局中build.grale文件添加
apply from:"config.gradle"
plugins {
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}
//引入config全局配置文件
apply from:"config.gradle"
task clean(type: Delete) {
delete rootProject.buildDir
}
- 配置module痒给,通過全局配置文件中的 isDebug 控制,來實現(xiàn)module和library之間的轉(zhuǎn)換骏全,我們對module中的build.grale文件作一下修改(這里修改的是module_login下面的)
apply from: '../config.gradle'
if (isDebug){
apply plugin: 'com.android.application'
}else {
apply plugin: 'com.android.library'
}
apply plugin:'org.jetbrains.kotlin.android'
apply plugin: 'kotlin-kapt'
android {
compileSdk rootProject.ext.android.compileSdkVersion
defaultConfig {
if (isDebug){
applicationId rootProject.ext.applicationid.lgoin
}
minSdk rootProject.ext.android.minSdkVersion
targetSdk rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext. android.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//kotlin 路由配置
kapt {
arguments {
arg("AROUTER_MODULE_NAME", project.getName())
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets{
main{
if (isDebug){
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
}else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation rootProject.ext.dependencies.corektx
implementation rootProject.ext.dependencies.appcompat
implementation rootProject.ext.dependencies.material
implementation rootProject.ext.dependencies.constraintlayout
testImplementation rootProject.ext.dependencies.junit
androidTestImplementation rootProject.ext.dependencies.junittest
androidTestImplementation rootProject.ext.dependencies.espressocore
implementation project(path: ':lib_common')
//kotlin路由配置
implementation rootProject.ext.libARouter
kapt rootProject.ext.libARouterCompiler
}
- 添加AndroidManifest.xml文件苍柏,這里解釋下為什么要添加AndroidManifest.xml。當module作為library庫時吟温,AndroidManifest.xml里面的內(nèi)容是有區(qū)別的
- 作為library序仙,目錄位置src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.module.login">
<application>
<activity
android:name="com.module.login.TestActivity" />
</application>
</manifest>
- 作為module單獨運行突颊,目錄位置src/main/debug/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.module.login">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name="com.module.login.App"
android:theme="@style/Theme.Demo">
<activity
android:name="com.module.login.TestActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- 完成上面幾步鲁豪,module_login模塊就配置完了潘悼,其他module依照配置就可以了。另外需要注意爬橡,組件開發(fā)治唤,一般會引入路由框架ARoute,實現(xiàn)模塊之間的的跳轉(zhuǎn)糙申。具體怎么實現(xiàn)宾添,請看ARoute使用
四、具體效果展示
- 當config.gradle配置文件中的 isDebug=true 時
圖2
- 當config.gradle配置文件中的 isDebug=false 時
圖3
五柜裸、總結(jié)
總的來說還算順利缕陕,期間就出現(xiàn)了些小問題,但還是值得注意
- 包重名問題疙挺,創(chuàng)建項目時沒注意扛邑,導(dǎo)致包重名了。Android修改包名
- 路由ARoute配置铐然,跳轉(zhuǎn)提示找不到路徑蔬崩,主要時因為我當時想試試java和kotlin不同配置,詳細請看Android路由ARoute使用
- 組件開發(fā)特別需要注意資源重名搀暑,為了避免這個問題沥阳,可以在module中的build.gradle中添加
resourcePrefix "xxx_"
前綴提示,這樣每次添加資源自点,系統(tǒng)會提示加前綴