組件化的優(yōu)點(diǎn)
- 編譯速度:可以按需測(cè)試單一模塊侣姆,因?yàn)槊恳粋€(gè)模塊都可以當(dāng)做一個(gè)application生真。
- 超級(jí)解耦:極度的降低了模塊之前的耦合,便于后期維護(hù)捺宗。
- 功能重用:某一塊的功能在另外的組件化項(xiàng)目中使用只需要單獨(dú)依賴這一模塊即可柱蟀,例如login模塊。
- 便于團(tuán)隊(duì)開(kāi)發(fā):適用于大團(tuán)隊(duì)分模塊各自開(kāi)發(fā)蚜厉,更好地團(tuán)隊(duì)協(xié)作长已,提升工作效率。
組件化需要注意的點(diǎn)
- 要注意包名和資源文件名的沖突
Gradle
中版本號(hào)的統(tǒng)一管理- 組件在
Application
和Library
之間如何做到隨意切換 AndroidManifest
文件的區(qū)分Library
不能在Gradle
文件中有applicationId
項(xiàng)目搭建
- 項(xiàng)目中新建模塊(
member
和cart
)
注意:要選擇
Application
昼牛,不要選擇Module
項(xiàng)目結(jié)構(gòu)
各個(gè)模塊都可直接運(yùn)行术瓮,因?yàn)槎际?code>Application。
- 編寫
common.gradle
:統(tǒng)一整個(gè)項(xiàng)目各個(gè)模塊的gradle贰健、依賴庫(kù)版本以及配置胞四,放在項(xiàng)目根目錄,與根build.gradle
平級(jí)
apply plugin: "com.android.application"
apply plugin: "kotlin-android"
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
}
注意:
common.gradle
中不要添加applicationId
- 各個(gè)模塊
apply from: "../common.gradle"
伶椿,刪除通用配置撬讽,保留獨(dú)有配置
apply from: "../common.gradle"
android {
defaultConfig {
applicationId "com.zt.member"
}
}
dependencies {
}
注意:
applicationId
添加到各自模塊中,因?yàn)槊總€(gè)模塊都是唯一的
- 使組件在
Application
和Library
之間隨意切換悬垃,其實(shí)就是apply plugin: "com.android.application"
還是apply plugin: "com.android.library"
編寫config.gradle
游昼,定義一個(gè)開(kāi)關(guān)isApplication
,也放在跟目錄
ext {
android = [
// true:所有組件均為application尝蠕;false:所有組件均為library
isApplication: true
]
}
切換只需要修改isApplication
的值即可烘豌。
- 在根
build.gradle
中引用config.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle"
buildscript {
...
}
allprojects {
...
}
- 修改
common.gradle
// app模塊一定為application,其他模塊參照配置
if (project.getName() == "app" || rootProject.ext.android.isApplication) {
apply plugin: "com.android.application"
} else {
apply plugin: "com.android.library"
}
apply plugin: "kotlin-android"
android {
...
}
dependencies {
...
}
到此為止看彼,你sync
整個(gè)項(xiàng)目廊佩,應(yīng)該是可以編過(guò),并且各個(gè)模塊也是可以單獨(dú)編譯成 App 的靖榕。
但是标锄,畢竟整個(gè)項(xiàng)目還是一個(gè)完整的 App ,那除了app
模塊是Application
外茁计,其他模塊應(yīng)該都是Library
料皇,那就修改isApplication: false
- 修改各個(gè)模塊的
gradle
文件,因?yàn)槿绻?code>Library的話,是不可以存在applicationId
的践剂。
apply from: "../common.gradle"
android {
defaultConfig {
if (rootProject.ext.android.isApplication) {
applicationId "com.zt.member"
}
}
}
dependencies {
}
既然是Library
鬼譬,那需要集成到app
模塊中
-
app
依賴其他組件,記得也要加上判斷
apply from: "../common.gradle"
android {
defaultConfig {
applicationId "com.zt.componentdemo"
}
}
dependencies {
// 只有當(dāng)模塊為L(zhǎng)ibrary時(shí)逊脯,才可以進(jìn)行依賴
if (!rootProject.ext.android.isApplication) {
implementation project(path: ":member")
implementation project(path: ":cart")
}
}
-
Androidmanifest
文件的區(qū)分优质,需要使得當(dāng)組件在Application
和Library
下加載不同的Androidmanifest
.
在模塊中新建manifest
文件夾,路徑:src/main/manifest
军洼,復(fù)制一份Androidmanifest.xml
到該文件夾巩螃,并修改成Library
適用的。
member 模塊
src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zt.member">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ComponentDemo">
<activity android:name=".MemberActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
src/main/manifest/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zt.member">
<application>
<activity android:name=".MemberActivity" />
</application>
</manifest>
- 修改
common.gradle
匕争,添加sourceSets
避乏,配置加載不同AndroidManifest
文件。
android {
...
sourceSets {
main {
// 指定AndroidManifest文件路徑
if (project.getName() == "app" || rootProject.ext.android.isApplication) {
manifest.srcFile "src/main/AndroidManifest.xml"
} else {
manifest.srcFile "src/main/manifest/AndroidManifest.xml"
}
}
}
}
- 如果組件是
Application
的話汗捡,每個(gè)模塊都需要一個(gè)xxxApplication
淑际,但是當(dāng)組件變成Library
的話畏纲,xxxApplication
就不需要了扇住,也不需要打包到最終的app
中,那就需要進(jìn)行配置了盗胀,思路與AndroidManifest
文件類似
在模塊中新建debug
文件夾(名字自人姨!),并添加包名票灰,隨后將臨時(shí)代碼文件添加到該目錄下女阀,如:xxxApplication.java
,xxxUtils.java
等等
member 模塊
并在common.gradle
中的sourceSets
里添加配置
sourceSets {
main {
// 指定AndroidManifest文件路徑
if (project.getName() == "app" || rootProject.ext.android.isApplication) {
manifest.srcFile "src/main/AndroidManifest.xml"
java.srcDirs "src/main/debug"
} else {
manifest.srcFile "src/main/manifest/AndroidManifest.xml"
}
}
}
注意:請(qǐng)注意
debug
前面圖標(biāo)的顏色,如果是藍(lán)色(isApplication: true
)屑迂,則表示這里面的java
文件會(huì)被編譯進(jìn)app
中浸策,如果是灰色(isApplication: false
),則表示不會(huì)惹盼。
-
java
代碼中區(qū)分模塊類型
首先現(xiàn)在common.gradle
中使用buildConfigField
添加參數(shù)
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0.0"
// 添加參數(shù)庸汗,便于在java文件中使用 buildConfigField type name value
buildConfigField "boolean", "isApplication", "$rootProject.ext.android.isApplication"
}
Make Project
之后,會(huì)在各個(gè)模塊的BuildConfig
文件中生成出該字段手报,這樣代碼中就可以使用了蚯舱。
BuildConfig 路徑
- 最后,可以再建立個(gè)common模塊掩蛤,這里新建選擇
Library
即可
common 模塊
別忘了在common.gradle
中添加依賴
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "com.google.android.material:material:1.2.1"
implementation "androidx.constraintlayout:constraintlayout:2.0.2"
implementation project (path: ":common")
}