從零開始Android組件化改造(二) - Gradle與Manifest管理

我的Github:https://github.com/BzCoder
本文基于MVPArms進行分析:https://github.com/JessYanCoding/MVPArms
歡迎各位留言討論

Gradle的管理在組件化改造中是一個非常有學問的環(huán)節(jié)。在我看來Gradle在其中的主要幾個職責:

  • 引入包的版本管理
  • 組件化編譯與總體編譯的切換
  • 各模塊間的層級關系維護
  • gradle.properties 配置中轉(zhuǎn)站

接下來我們就一點一點的講。

1.引入包的版本管理

這其實不是組件化開發(fā)的專利最疆。正如其他的項目一樣叹卷,統(tǒng)一的版本號我們都管理在Config.gradle中赁项。類似下面的文件然想。在模塊中引入模塊時,統(tǒng)一通過類似api rootProject.ext.dependencies["mmkv"]的引入方式來保證版本的統(tǒng)一询吴。這個很好理解齿尽,因為都是常規(guī)操作沽损。

ext {

    android = [
            applicationId    : "${PACKAGE_NAME}",
            compileSdkVersion: 28,
            buildToolsVersion: "28.0.3",
            minSdkVersion    : 18,
            targetSdkVersion : 28,
            versionCode      : VERSION_CODE as int,
            versionName      : "${VERSION_NAME}"
    ]

    version = [
            androidSupportSdkVersion: "28.0.0",
            retrofitSdkVersion      : "2.4.0",
            dagger2SdkVersion       : "2.19",
    ]

    dependencies = [
            //support
            "appcompat-v7"             : "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}",
            "design"                   : "com.android.support:design:${version["androidSupportSdkVersion"]}",
            "support-v4"               : "com.android.support:support-v4:${version["androidSupportSdkVersion"]}",
            "cardview-v7"              : "com.android.support:cardview-v7:${version["androidSupportSdkVersion"]}",
            "annotations"              : "com.android.support:support-annotations:${version["androidSupportSdkVersion"]}",
            "recyclerview-v7"          : "com.android.support:recyclerview-v7:${version["androidSupportSdkVersion"]}",
            "constraint-layout"        : 'com.android.support.constraint:constraint-layout:1.1.3',
]
  defaultConfig {
        minSdkVersion rootProject.ext.android["minSdkVersion"]
        targetSdkVersion rootProject.ext.android["targetSdkVersion"]
        versionCode rootProject.ext.android["versionCode"]
        versionName rootProject.ext.android["versionName"]
        testInstrumentationRunner rootProject.ext.dependencies["androidJUnitRunner"]
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
                includeCompileClasspath true
            }
        }

        multiDexEnabled true
    }

2.組件化編譯與總體編譯的切換

2.1 App與Lib

我們知道,lib模塊需要引入apply plugin: 'com.android.library'循头,應用模塊引入apply plugin: 'com.android.application'绵估,而在組件化開發(fā)中炎疆,這兩種狀態(tài)是要不斷地切換的,所以我們可以在gradle.properties設定參數(shù)isBuildModule來控制国裳。于是gradle的頭部就變成了以下

if (isBuildModule.toBoolean()) {
    apply plugin: 'com.android.application'

} else {
    apply plugin: 'com.android.library'
}

當然在實際開發(fā)中我們設計了多層形入,相應的我們也給每層建立了基礎gradle,參數(shù)也隨之變成了isBuildModuleOne缝左,isBuildModuleTwo亿遂,isBuildModuleThree...每一層的業(yè)務只要依賴該層基礎gradle即可。

2.2 兩套Manifest

組件化編譯和整體編譯渺杉,他們的清單文件也是不同的蛇数。我們通過在Gradle中android節(jié)點中加入以下代碼來控制工程使用兩套Manifest,但是這種方案美中不足的是是越,你的每個Activity的注冊都必須要寫兩次耳舅,否則切換編譯模式后,會出現(xiàn)錯誤倚评,有待改進浦徊。

 sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            if (isBuildModule.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }

2.3 不同編譯方式時導入不同的包

說到包的導入,我們先必須明確兩個關鍵字的概念蔓纠。

  • runtimeOnly:只有在運行時才編譯辑畦。
  • compileOnly:只有編譯的時候引入吗蚌,實際打包時并不會加入到包當中腿倚。

根據(jù)以上原則
在模塊互相導入時,我們使用如下格式:

  if (isBuildModule.toBoolean()) {
 if (moduleXX.toBoolean()) {
     runtimeOnly project(":moduleXX")
}
}

這樣寫蚯妇,首先(if語句)可以通過配置文件來確認某個模塊是否加入敷燎,使用runtimeOnly ,可以在某一個Module組件化編譯時箩言,不會影響其他引用它的模塊硬贯。還有一點,我們在引用的外層包裹了一層是否為組件化編譯的狀態(tài)判斷(isBuildModule)陨收,這是為了防止模塊的重復引入饭豹。因為在組件化開發(fā)時,模塊之間是不需要互相顯式引用的务漩,我們最終的模塊引用是通過APP引用的拄衰。

在通用模塊導入時,我們使用如下格式:
butterknife饵骨,dagger2等包引入翘悉。

   if (isBuildModule.toBoolean()) {
        //view
        annotationProcessor(rootProject.ext.dependencies["butterknife-compiler"]) {
            exclude module: 'support-annotations'
        }
        //tools
        annotationProcessor rootProject.ext.dependencies["dagger2-compiler"]
        annotationProcessor rootProject.ext.dependencies["arouter-compiler"]
        //test
        debugImplementation rootProject.ext.dependencies["canary-debug"]
        releaseImplementation rootProject.ext.dependencies["canary-release"]
        testImplementation rootProject.ext.dependencies["canary-release"]
    } else {
        compileOnly rootProject.ext.dependencies["butterknife-compiler"]
        compileOnly rootProject.ext.dependencies["dagger2-compiler"]
        compileOnly rootProject.ext.dependencies["arouter-compiler"]
        compileOnly rootProject.ext.dependencies["canary-debug"]
        compileOnly rootProject.ext.dependencies["canary-release"]
    }

這樣寫只有在組件化編譯的時候,模塊才會真正把基礎包引入居触,整體打包時妖混,只有一份老赤。

3.Manifest與gradle.properties的數(shù)據(jù)橋梁

因為我們目標想把所有的配置文件都整合到gradle.properties中,但是manifest又不能直接調(diào)用gradle.properties中的參數(shù)制市,我們就必須借助gradle作為“中間人”抬旺。我們在gradle的defaultconfig節(jié)點中加入(以下為推送的寫法)

 manifestPlaceholders = [
                GETUI_APP_ID    : "${PUSH_APPID}",
                GETUI_APP_KEY   : "${PUSH_APPKEY}",
                GETUI_APP_SECRET: "${PUSH_APPSECRET}"
]

這樣一來,在Manifest中就可以取到gradle.properties 的參數(shù)了息堂。

總結(jié)

Gradle配置總的來說不是太難嚷狞,以上方案也存在可以優(yōu)化的地方,就是Manifest荣堰,攜程曾經(jīng)有一篇文件是利用manifest的tools:node ="remove"來進行manifest的合并床未,但是很可惜,在我自己實踐的過程中振坚,遇到了不少困難薇搁,最終沒有采用攜程的方案。好的渡八,那么今天的文章就先暫時寫到這里啃洋。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市屎鳍,隨后出現(xiàn)的幾起案子宏娄,更是在濱河造成了極大的恐慌,老刑警劉巖逮壁,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孵坚,死亡現(xiàn)場離奇詭異,居然都是意外死亡窥淆,警方通過查閱死者的電腦和手機卖宠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忧饭,“玉大人扛伍,你說我怎么就攤上這事〈士悖” “怎么了刺洒?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吼砂。 經(jīng)常有香客問我逆航,道長,這世上最難降的妖魔是什么帅刊? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任纸泡,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘女揭。我一直安慰自己蚤假,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布吧兔。 她就那樣靜靜地躺著磷仰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪境蔼。 梳的紋絲不亂的頭發(fā)上灶平,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音箍土,去河邊找鬼逢享。 笑死,一個胖子當著我的面吹牛吴藻,可吹牛的內(nèi)容都是我干的瞒爬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沟堡,長吁一口氣:“原來是場噩夢啊……” “哼侧但!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起航罗,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤禀横,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粥血,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柏锄,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年立莉,在試婚紗的時候發(fā)現(xiàn)自己被綠了绢彤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片七问。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜓耻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出械巡,到底是詐尸還是另有隱情刹淌,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布讥耗,位于F島的核電站有勾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏古程。R本人自食惡果不足惜蔼卡,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挣磨。 院中可真熱鬧雇逞,春花似錦荤懂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掉蔬,卻和暖如春廊宪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背女轿。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工箭启, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛉迹。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓册烈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親婿禽。 傳聞我的和親對象是個殘疾皇子赏僧,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容