Android-架構(gòu)-組件化開(kāi)發(fā)(一):項(xiàng)目搭建

組件化的優(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)一管理
  • 組件在ApplicationLibrary之間如何做到隨意切換
  • AndroidManifest文件的區(qū)分
  • Library不能在Gradle文件中有applicationId

項(xiàng)目搭建

  1. 項(xiàng)目中新建模塊(membercart

注意:要選擇Application昼牛,不要選擇Module

項(xiàng)目結(jié)構(gòu)

各個(gè)模塊都可直接運(yùn)行术瓮,因?yàn)槎际?code>Application。

  1. 編寫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

  1. 各個(gè)模塊apply from: "../common.gradle"伶椿,刪除通用配置撬讽,保留獨(dú)有配置
apply from: "../common.gradle"

android {
    defaultConfig {
        applicationId "com.zt.member"
    }
}

dependencies {
}

注意:applicationId添加到各自模塊中,因?yàn)槊總€(gè)模塊都是唯一的

  1. 使組件在ApplicationLibrary之間隨意切換悬垃,其實(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的值即可烘豌。

  1. 在根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 {
    ...
}
  1. 修改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

  1. 修改各個(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模塊中

  1. 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")
    }
}
  1. Androidmanifest文件的區(qū)分优质,需要使得當(dāng)組件在ApplicationLibrary下加載不同的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>
  1. 修改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"
            }
        }
    }
}
  1. 如果組件是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ì)惹盼。

  1. 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 路徑

  1. 最后,可以再建立個(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")
}

整個(gè)項(xiàng)目已搭建完成枉昏,組件化開(kāi)發(fā)中還有最重要的兩個(gè)點(diǎn),路由和通信揍鸟,會(huì)在后面兩篇文章中進(jìn)行分享兄裂。

github地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子懦窘,更是在濱河造成了極大的恐慌前翎,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畅涂,死亡現(xiàn)場(chǎng)離奇詭異港华,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)午衰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門立宜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人臊岸,你說(shuō)我怎么就攤上這事橙数。” “怎么了帅戒?”我有些...
    開(kāi)封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵灯帮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我逻住,道長(zhǎng)钟哥,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任瞎访,我火速辦了婚禮腻贰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扒秸。我一直安慰自己播演,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布伴奥。 她就那樣靜靜地躺著写烤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拾徙。 梳的紋絲不亂的頭發(fā)上洲炊,一...
    開(kāi)封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音锣吼,去河邊找鬼选浑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛玄叠,可吹牛的內(nèi)容都是我干的古徒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼读恃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼隧膘!你這毒婦竟也來(lái)了代态?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤疹吃,失蹤者是張志新(化名)和其女友劉穎蹦疑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體萨驶,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歉摧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腔呜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叁温。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖核畴,靈堂內(nèi)的尸體忽然破棺而出膝但,到底是詐尸還是另有隱情,我是刑警寧澤谤草,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布跟束,位于F島的核電站,受9級(jí)特大地震影響丑孩,放射性物質(zhì)發(fā)生泄漏冀宴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一嚎杨、第九天 我趴在偏房一處隱蔽的房頂上張望花鹅。 院中可真熱鬧氧腰,春花似錦枫浙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至黄痪,卻和暖如春紧帕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桅打。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工是嗜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挺尾。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓鹅搪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親遭铺。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丽柿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359