組件化項(xiàng)目部署實(shí)例

1、組件化項(xiàng)目的意義

開(kāi)發(fā)需求:不相互依賴、可以相互交互、任意組合、高度解耦
團(tuán)隊(duì)效率:分模塊打包、測(cè)試、統(tǒng)一版本管理>


2、Phone Module和Android Library區(qū)別、切換
3、新建common公共庫(kù)、order訂單庫(kù)、personal個(gè)人信息庫(kù)

模塊中有小綠點(diǎn)的是可以單獨(dú)運(yùn)行的,模塊中有柱狀圖的是不可以單獨(dú)運(yùn)行的。在做組件化模式的時(shí)候需要子模塊可以獨(dú)立運(yùn)行,在做集成化模式的時(shí)候需要打包整個(gè)項(xiàng)目apk,子模塊不可獨(dú)立運(yùn)行。

4、gradle搭建組件化項(xiàng)目環(huán)境

環(huán)境:Android Studio3.4.1+Gradle5.1.1
思考:我們?cè)谛薷陌姹咎?hào)的時(shí)候,需要修改各個(gè)子模塊中的版本號(hào),萬(wàn)一漏了有一個(gè)怎么辦?這個(gè)時(shí)候就需要把版本號(hào)與引入的第三方庫(kù)統(tǒng)一管理起來(lái)。
\color{red}{在項(xiàng)目的根目錄下面新建一個(gè)config.gradle文件,用于做版本與引入三方庫(kù)的統(tǒng)一管理}\

//如果要添加多個(gè)自定義的屬性,需要在ext代碼塊中引入
ext {
    // 定義一個(gè)項(xiàng)目全局變量isRelease,用于動(dòng)態(tài)切換:組件化模式 / 集成化模式
    // false: 組件化模式(子模塊可以獨(dú)立運(yùn)行),true :集成化模式(打包整個(gè)項(xiàng)目apk,子模塊不可獨(dú)立運(yùn)行)
    isRelease = false
    // 建立Map存儲(chǔ),對(duì)象名、key可以自定義
    androidId = [
            compileSdkVersion: 28,
            buildToolsVersion: "29.0.0",
            minSdkVersion    : 24,
            targetSdkVersion : 28,
            versionCode      : 1,
            versionName      : "1.0"
    ]

    appId = ["app"     : "com.migill.modular",
             "order"   : "com.migill.modular.order",
             "personal": "com.migill.modular.personal"]

    url = [
            "debug"  : "https://11.22.33.44/debug",
            "release": "https://55.66.77.88/release"
    ]
    supportLibrary = "28.0.0"
    dependencies = [
            // ${supportLibrary}表示引用一個(gè)變量
            "appcompat"   : "com.android.support:appcompat-v7:${supportLibrary}",
            "recyclerview": "com.android.support:recyclerview-v7:${supportLibrary}",
            "constraint"  : "com.android.support.constraint:constraint-layout:1.1.3",
            "okhttp3"     : "com.squareup.okhttp3:okhttp:3.10.0",
            "retrofit"    : "com.squareup.retrofit2:retrofit:2.5.0",
            "fastjson"    : "com.alibaba:fastjson:1.2.58",
    ]
}

\color{red}{在根目錄的build.gradle頭部加入自定義gradle}\

apply from: "config.gradle"

\color{red}{修改app模塊下的build.gradle文件}\

1、buildConfigField("boolean", "isRelease", String.valueOf(isRelease))這句是什么意思?
是在BuildConfig文件中新增一個(gè)isRelease屬性。


2、為什么是在isRelease為true的時(shí)候引入order和personal 模塊?
是因?yàn)閕sRelease為false的時(shí)候是組件化模式,order與personal模塊都是application模塊,application模塊是不能引用application模塊的。

apply plugin: 'com.android.application'

def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        // app子模塊在組件化開(kāi)發(fā)中,默認(rèn)為application
        applicationId appId.app
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        // 切記:不能在android根節(jié)點(diǎn),只能在defaultConfig或buildTypes節(jié)點(diǎn)下
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循環(huán)引入第三方庫(kù)
    support.each { k, v -> implementation v }
    implementation project(':common') // 公共基礎(chǔ)庫(kù)
    // 如果是集成化模式,做發(fā)布版本時(shí)。各個(gè)模塊都不能獨(dú)立運(yùn)行了
    if (isRelease) {
        implementation project(':order')
        implementation project(':personal')
    }
}

\color{red}{修改order模塊下的build.gradle文件}\

  • isRelease=true:集成化模式(打包整個(gè)項(xiàng)目apk,子模塊不可獨(dú)立運(yùn)行)需要配置成Android Library
  • isRelease=false:組件化模式(子模塊可以獨(dú)立運(yùn)行)需要配置成Phone Module
if (isRelease) { // 如果是發(fā)布版本時(shí),各個(gè)模塊都不能獨(dú)立運(yùn)行
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        if (!isRelease) { // 如果是集成化模式,不能有applicationId
            applicationId appId.order // 組件化模式能獨(dú)立運(yùn)行才能有applicationId
        }
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循環(huán)引入第三方庫(kù)
    support.each { k, v -> implementation v }
    implementation project(':common') // 公共基礎(chǔ)庫(kù)
}

\color{red}{修改personal模塊下的build.gradle文件}\

if (isRelease) { // 如果是發(fā)布版本時(shí),各個(gè)模塊都不能獨(dú)立運(yùn)行
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

def rootAndroidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion rootAndroidId.compileSdkVersion
    buildToolsVersion rootAndroidId.buildToolsVersion
    defaultConfig {
        if (!isRelease) { // 如果是集成化模式,不能有applicationId
            applicationId appId.personal // 組件化模式能獨(dú)立運(yùn)行才能有applicationId
        }
        minSdkVersion rootAndroidId.minSdkVersion
        targetSdkVersion rootAndroidId.targetSdkVersion
        versionCode rootAndroidId.versionCode
        versionName rootAndroidId.versionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循環(huán)引入第三方庫(kù)
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    support.each { k, v -> implementation v }
    implementation project(':common') // 公共基礎(chǔ)庫(kù)
}

總結(jié):app、order、personal模塊的build.gradle的修改都是圍繞如下兩點(diǎn):

  • 第一點(diǎn),配置成統(tǒng)一管理的版本號(hào)等等。
  • 第二點(diǎn),根據(jù)isRelease配置成是組件化模式還是繼承化模式
5、集成化模式開(kāi)發(fā)、組件化模式開(kāi)發(fā)
6、組件化開(kāi)發(fā)的臨時(shí)代碼,集成化打包時(shí)動(dòng)態(tài)隔離

思考:比如我們?cè)趏rder中創(chuàng)建了A、B、C三個(gè)測(cè)試類,在集成環(huán)境打包的時(shí)候,我不希望打包到APK中去,這個(gè)怎么辦呢?


這個(gè)時(shí)候就可以用到資源配置,方便測(cè)試環(huán)境,打包不繼承到正式環(huán)境

如下圖,在main下創(chuàng)建debug目錄放AndroidManifest.xml文件,在com.migill.modular.order.debug下放測(cè)試的文件

修改isRelease = true,編譯正式的APK,可以發(fā)現(xiàn)A、B、C、Order_DebugActivity都沒(méi)有打包到正式環(huán)境中。

修改isRelease = false,單獨(dú)運(yùn)行order模塊。首頁(yè)就變成了Order_DebugActivity的頁(yè)面了。

android {
...
    // 配置資源路徑,方便測(cè)試環(huán)境,打包不集成到正式環(huán)境
    sourceSets {
        main {
            if (!isRelease) {
                // 如果是組件化模式,需要單獨(dú)運(yùn)行時(shí)
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                // 集成化模式,整個(gè)項(xiàng)目打包apk
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    // release 時(shí) debug 目錄下文件不需要合并到主工程
                    exclude '**/debug/**'
                }
            }
        }
    }
...
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容