第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Gradle 運(yùn)用在組件化中

前面幾節(jié)我們學(xué)習(xí)了 Gradle 的任務(wù),命令已經(jīng)學(xué)會(huì)了自定義插件。那么下面我們就來學(xué)習(xí)以下如何將前面所學(xué)的 Gradle 知識(shí)運(yùn)用在組件化架構(gòu)中。我們現(xiàn)在的項(xiàng)目基本都是組件化的架構(gòu)。但是我們真的了解組件化嗎?我們通過這節(jié)學(xué)習(xí),希望能夠幫助到大家在組件化開發(fā)中有更高的效率。

1. 組件化與集成化

我們的項(xiàng)目最開始創(chuàng)建時(shí)是集成化模式的,但是由于我們一個(gè)團(tuán)隊(duì),有很多人在同時(shí)開發(fā)一個(gè)項(xiàng)目,但是大家都負(fù)責(zé)各自的模塊。這樣在集成化的模式下,大家要編譯跟大家不相關(guān)的別的模塊相關(guān)的代碼。所以就出現(xiàn)的組件化模式。在組件化模式下,各個(gè)模塊可以獨(dú)立運(yùn)行。

集成化模式: 就是打包整個(gè)項(xiàng)目,編譯出一個(gè)全業(yè)務(wù)功能的 apk 文件。各個(gè)子模塊不能夠獨(dú)立運(yùn)行,只能依賴于宿主 App。
組件化模式: 就是每個(gè)子模塊都能夠獨(dú)立運(yùn)行,不需要依賴宿主 APP 殼。而且每個(gè)模塊都能夠編譯出 apk 文件。

2. Android 項(xiàng)目中組件化運(yùn)用

我們下面來具體看下 Android 項(xiàng)目中我們?cè)趺磥韺?shí)施組件化。我們知道我們發(fā)布市場(chǎng)肯定是要打一個(gè)全功能的 apk 包,也就是發(fā)布市場(chǎng)時(shí)是需要集成化的打包模式,而我們開發(fā)過程中是需要組件化模式的,所以我們需要一個(gè)開關(guān)來控制組件化和集成化打包模式。我們各個(gè)模塊都會(huì)有編譯工具版本,SDK 的版本,support 庫的版本號(hào)等。我們可以將這些抽離出來,單獨(dú)建立一個(gè) Gradle 文件來配置這些全局變量。

2.1 config.gradle

我們創(chuàng)建一個(gè)單獨(dú)的config.gradle文件,定義全局變量,如下所示:

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    : 19,
            targetSdkVersion : 28,
            versionCode      : 1,
            versionName      : "1.0"
    ]

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

  
    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",
    ]
}

2.2 在 build.gradle 中引用 config.gradle

我們要引用我們上面定義的 config.gradle 文件,就需要在項(xiàng)目的根目錄下的 build.gradle 中加入以下代碼

apply from: "config.gradle"

2.3 在 module 中引用公共變量

前面我們?cè)?config 定義了我們各個(gè)模塊可能都會(huì)用到的依賴庫,編譯版本,sdk 版本版本號(hào)等一些公共變量。下面我們就需要將這些變量在 module 的 build.gradle 中引入。這里我創(chuàng)建了一個(gè)項(xiàng)目有 common,order,person 以及主模塊 app 四個(gè) module,下面我們以 order 為例。

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"
        //當(dāng)前項(xiàng)目的build.config文件里添加了一個(gè)boolean類型的變量 
        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)引入第三方庫
    support.each { k, v -> implementation v }
    implementation project(':common') // 公共基礎(chǔ)庫
}

Tips:這里我們?cè)谇懊婕尤肓?code>buildConfigField,這個(gè)的作用是在當(dāng)前模塊的 build.config 中加入一個(gè) isRelease 的布爾型變量。因?yàn)?src 代碼中有可能需要用到跨模塊交互,如果是組件化模塊顯然不能跨模塊交互的。

2.4 在 module 的 build.gradle 中使用 isRelease 開關(guān)

我們引入定義的變量后,我們就需要在 module 中引入組件化開關(guān),這里我們用 isRelease 表示,如果 isRelease 為 true,則表示當(dāng)前為集成化模式,否則當(dāng)前為組件化模式,各模塊可相互獨(dú)立。

Tips: 我們知道默認(rèn)創(chuàng)建項(xiàng)目只有 app 模塊才能運(yùn)行,那么我們現(xiàn)在組件化中需要各個(gè)模塊都能獨(dú)立運(yùn)行,那么我們就需要根據(jù) isRelease 開關(guān)來控制了。能夠獨(dú)立運(yùn)行取決于為 build.gradle 第一行引入的是com.android.library還是com.android.application,只有引入后者module才能獨(dú)立運(yùn)行。
根據(jù)上面的知識(shí),我們應(yīng)該在 module 中加入:

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

2.5 配置資源路徑

由于組件化和集成化模式中,module 的 AndroidManifest.xml 文件是不同的,組件化時(shí),module 可以獨(dú)立運(yùn)行,AndroidManifest.xml 中需要配置 appliation、啟動(dòng) activity 等。而集成化運(yùn)行時(shí)只有主模塊可以配置。所以這里我們就需要這么配置。

// 配置資源路徑
    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'
            }
        }
    }

2.6 配置組件化測(cè)試

我們?cè)陂_發(fā)中可能都會(huì)遇到,自己的模塊運(yùn)行需要?jiǎng)e的模塊的數(shù)據(jù),當(dāng)沒有集成別的模塊的數(shù)據(jù)時(shí),我們可以寫一些自己的測(cè)試數(shù)據(jù),或是資源文件等等。就是只有在組件化中能夠用到,但是不需要出現(xiàn)在集成化打包后的生產(chǎn)包中的,我們可以單獨(dú)創(chuàng)建一個(gè)文件夾,集合化時(shí)使用exclude不要讓這個(gè)文件夾合并到項(xiàng)目中。具體如下所示:

    // 配置資源路徑
    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/**'
                }
            }
        }
    }

Tips: exclude 的妙用非常多,如果我們一些測(cè)試代碼,測(cè)試數(shù)據(jù),或是組件化單獨(dú)的資源文件我們都可以放在 debug 文件下。編譯的時(shí)候 exclude 會(huì)將這個(gè)模塊所有的 debug 文件夾下的文件不會(huì)合并到整個(gè)項(xiàng)目中去。

2.7 完整的 module 的配置

前面我們的配置都是將 order 模塊的 build.config,單獨(dú)拆各個(gè)模塊來講的??赡艽蠹矣悬c(diǎn)亂。下面我們看下完整的配置應(yīng)該是怎樣的。

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'
        }
    }

    // 配置資源路徑
    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/**'
                }
            }
        }
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循環(huán)引入第三方庫
    support.each { k, v -> implementation v }
    implementation project(':common') // 公共基礎(chǔ)庫
}

3. 小結(jié)

本節(jié),我們帶大家學(xué)習(xí)了 Gradle 在 Android 項(xiàng)目組件化中的運(yùn)用。主要知識(shí)點(diǎn)有以下幾點(diǎn):

  • 配置公共的依賴 jar 包,編譯版本,構(gòu)建版本,版本號(hào)等。
  • 用 buildConfigField 將組件化開關(guān)添加到 build.config 中,這樣 Java 代碼也就可以使用組件化開關(guān)。
  • 配置資源文件,可以將我們的測(cè)試資源、代碼放在一個(gè)單獨(dú)的目錄下,使用 exclude,將這個(gè)目錄下的文件不合并到項(xiàng)目。