天天看點

【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ② ( 元件化基本實作 | Project 相關目錄 | 定義元件切換标志位 | 切換插件導入 | 切換設定應用 ID )

文章目錄

  • ​​一、Project 中可擷取的目錄​​
  • ​​二、定義子產品化與元件化切換标志位​​
  • ​​三、切換插件導入​​
  • ​​四、切換設定應用 ID​​

在上一篇部落格 ​​【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ① ( 元件化簡介 | 建立元件化應用 | 依賴庫子產品 / 應用子產品 切換設定 )​​ 最後提到了 在 Gradle 建構腳本中 , 需要實作 依賴庫子產品 / 應用子產品 切換設定

  • build.gradle 建構腳本 切換設定 , 切換 應用 / 依賴庫 ;
  • AndroidManifest.xml 清單檔案 切換設定 , 設定 啟動 Activity 項 ;

本篇部落格開始 編寫上述 Gradle 腳本 ;

GitHub 位址 : ​​https://github.com/han1202012/Componentization​​

一、Project 中可擷取的目錄

在進行建構腳本實作之前 , 先介紹 下 Project 的相關目錄 , 調用 Project 執行個體對象中的相關函數

  • 工程的根目錄 ,
  • 建構腳本入口所在目錄 ,
  • 編譯目錄 ,

等檔案目錄 , 之後需要使用到這些目錄 ;

建構腳本中擷取 Project 執行個體對象 : 在 build.gradle 建構腳本 中 , 通過調用 Project#getRootProject 函數

/**
     * <p>傳回此項目所屬層次結構的根項目。對于單個項目生成,此方法傳回此項目。</p>
     *
     * @return 根項目。從不傳回null。
     */
    Project getRootProject();      

在 Project 執行個體對象中 , 可擷取如下三個目錄 : buildDir 編譯目錄 ,rootDir 根目錄 ;

【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ② ( 元件化基本實作 | Project 相關目錄 | 定義元件切換标志位 | 切換插件導入 | 切換設定應用 ID )
  • buildDir : 工程根目錄 下的 build 目錄 ;
/**
     * <p>傳回此項目的生成目錄。建構目錄是生成所有工件的目錄。
     * 生成目錄的預設值為 <code><i>projectDir</i>/build</code></p>
     *
     * @return 生成目錄。從不傳回null。
     */
    File getBuildDir();      
【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ② ( 元件化基本實作 | Project 相關目錄 | 定義元件切換标志位 | 切換插件導入 | 切換設定應用 ID )
  • projectDir : 通過調用 Project#getProjectDir 函數 獲得 ; 下圖中 工程根目錄 build.gradle 頂層建構腳本 放在了該 工程的根目錄 中 , 是以 projectDir 就是工程的根目錄 ;
/**
     * <p>包含工程建構腳本的目錄, 一般是根目錄。</p>
     *
     * @return 工程目錄。從不傳回null。
     */
    File getProjectDir();      
【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ② ( 元件化基本實作 | Project 相關目錄 | 定義元件切換标志位 | 切換插件導入 | 切換設定應用 ID )
  • rootDir : 調用 Project#getRootDir 方法 , 傳回工程的根目錄 ; 一般與 Project#getProjectDir 函數擷取的工程目錄 是同一個目錄 ;
/**
     * <p>傳回此項目的根目錄。根目錄是根項目的項目目錄。</p>
     *
     * @return 根目錄。從不傳回null。
     */
    File getRootDir();      
【Android Gradle 插件】元件化中的 Gradle 建構腳本實作 ② ( 元件化基本實作 | Project 相關目錄 | 定義元件切換标志位 | 切換插件導入 | 切換設定應用 ID )

二、定義子產品化與元件化切換标志位

在 工程根目錄 中 , 建立 common.gradle 建構腳本 , 用于存放一些 擴充變量 ;

定義 isModuleDebug 變量 用于控制目前的運作模式 :

  • 元件化模式 : 在 Debug 開發階段, 每個子產品都可以獨立運作, 是以相關的子產品都是 Application 應用子產品, 此時, isModuleDebug 設定為 true. ( 單獨運作 ) ;
  • 子產品化模式 : 在 Release 釋出階段, 隻有一個殼應用是可以獨立運作的, 其它所有的子產品都作為依賴庫存在, 此時, isModuleDebug 設定為 false. ( 非單獨運作 ) ;
/**
 * 定義 Project 對象的 ext 屬性擴充
 */
project.ext {
    /**
     * 該變量控制目前的運作模式
     *      在 Debug 開發階段, 每個子產品都可以獨立運作, 是以相關的子產品都是 Application 應用子產品,
     * 此時, isModuleDebug 設定為 true. ( 單獨運作 )
     *      在 Release 釋出階段, 隻有一個殼應用是可以獨立運作的, 其它所有的子產品都作為依賴庫存在,
     * 此時, isModuleDebug 設定為 false. ( 非單獨運作 )
     */
    isModuleDebug = false
}      

如果需要使用上述 isModuleDebug 變量 , 隻需要使用 ​

​apply from: common.gradle​

​ 代碼 , 在目前腳本中 引入上述 common.gradle 建構腳本即可 ;

三、切換插件導入

在子產品下的 build.gradle 建構腳本 中 , 預設的 " Phone & Tablet " 類型的 Module 子產品

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}      

引入元件化後 ,

  • 在 子產品化模式 中 , 需要導入 ​

    ​com.android.library​

    ​ 插件 , 子產品作為 依賴庫 使用 , 是 " Android Library " 類型的 Module 子產品 ;
  • 在 元件化模式 中 , 需要導入 ​

    ​com.android.application​

    ​ 插件 , 子產品作為 可執行應用 使用 , 是 " Phone & Tablet " 類型的 Module 子產品 ;

通過在 common.gradle 建構腳本 中 對 Project 類的 isModuleDebug 擴充屬性配置 , 使用該屬性控制目前應用是處于 子產品化 還是 元件化

首先 , apply from 引入建構腳本的操作, 等同于将該建構腳本原封不動拷貝到此處 ; ​

​${rootProject.rootDir}​

​ 的作用是擷取工程根目錄 , common.gradle 建構腳本就是定義在根目錄中 ;

然後 , 根據 isModuleDebug 擴充屬性 , 導入不同的 Android Gradle Plugin 插件 ,

  • 如果是 元件化 導入 com.android.application 插件 ;
  • 如果是 子產品化 導入 com.android.library 插件 ;

建構腳本實作如下 :

/**
 * rootProject.projectDir 是工程的根目錄
 * apply from 引入建構腳本的操作, 等同于将該建構腳本原封不動拷貝到此處
 */
apply from: "${rootProject.rootDir}/common.gradle"

if (project.isModuleDebug) {
    /**
     * 元件化 : 在 Debug 開發階段, 每個子產品都可以獨立運作, 是以相關的子產品都是 Application 應用子產品,
     *         此時, isModuleDebug 設定為 true. ( 單獨運作 )
     * 元件化導入 com.android.application 插件
     */
    apply plugin: 'com.android.application'

} else {
    /**
     * 子產品化 : 在 Release 釋出階段, 隻有一個殼應用是可以獨立運作的, 其它所有的子產品都作為依賴庫存在,
     *         此時, isModuleDebug 設定為 false. ( 非單獨運作 )
     * 子產品化導入 com.android.library 插件
     */
    apply plugin: 'com.android.library'
}      

四、切換設定應用 ID

通過在 common.gradle 建構腳本 中 對 Project 類的 isModuleDebug 擴充屬性配置 , 使用該屬性控制目前應用是處于 子產品化 還是 元件化

  • 如果是 元件化狀态 , 該子產品可以獨立運作 , 必須定義 applicationId
  • 如果是 子產品化狀态 , 該子產品作為依賴庫存在 , 不能定義 applicationId ;

android#defaultConfig#applicationId 配置示例 :

android {
    defaultConfig {
        if (project.isModuleDebug) {
            /**
             * 子產品化時才能設定 applicationId
             * 依賴庫設定 applicationId 編譯時會報錯
             */
            applicationId "kim.hsl.business"
        }
    }
}      
/*plugins {
    id 'com.android.application'
    id 'kotlin-android'
}*/

/**
 * rootProject.projectDir 是工程的根目錄
 * apply from 引入建構腳本的操作, 等同于将該建構腳本原封不動拷貝到此處
 */
apply from: "${rootProject.rootDir}/common.gradle"

if (project.isModuleDebug) {
    /**
     * 元件化 : 在 Debug 開發階段, 每個子產品都可以獨立運作, 是以相關的子產品都是 Application 應用子產品,
     *         此時, isModuleDebug 設定為 true. ( 單獨運作 )
     * 元件化導入 com.android.application 插件
     */
    apply plugin: 'com.android.application'

} else {
    /**
     * 子產品化 : 在 Release 釋出階段, 隻有一個殼應用是可以獨立運作的, 其它所有的子產品都作為依賴庫存在,
     *         此時, isModuleDebug 設定為 false. ( 非單獨運作 )
     * 子產品化導入 com.android.library 插件
     */
    apply plugin: 'com.android.library'
}

/**
 * 導入 Kotlin 插件
 */
apply plugin: 'kotlin-android'

android {
    compileSdkVersion 32
    buildToolsVersion "32.0.0"

    defaultConfig {
        if (project.isModuleDebug) {
            /**
             * 子產品化時才能設定 applicationId
             * 依賴庫設定 applicationId 編譯時會報錯
             */
            applicationId "kim.hsl.business"
        }
        minSdkVersion 18
        targetSdkVersion 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    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.8.0'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}