文章目錄
- 一、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 根目錄 ;
- buildDir : 工程根目錄 下的 build 目錄 ;
/**
* <p>傳回此項目的生成目錄。建構目錄是生成所有工件的目錄。
* 生成目錄的預設值為 <code><i>projectDir</i>/build</code></p>
*
* @return 生成目錄。從不傳回null。
*/
File getBuildDir();
- projectDir : 通過調用 Project#getProjectDir 函數 獲得 ; 下圖中 工程根目錄 build.gradle 頂層建構腳本 放在了該 工程的根目錄 中 , 是以 projectDir 就是工程的根目錄 ;
/**
* <p>包含工程建構腳本的目錄, 一般是根目錄。</p>
*
* @return 工程目錄。從不傳回null。
*/
File getProjectDir();
- rootDir : 調用 Project#getRootDir 方法 , 傳回工程的根目錄 ; 一般與 Project#getProjectDir 函數擷取的工程目錄 是同一個目錄 ;
/**
* <p>傳回此項目的根目錄。根目錄是根項目的項目目錄。</p>
*
* @return 根目錄。從不傳回null。
*/
File getRootDir();
二、定義子產品化與元件化切換标志位
在 工程根目錄 中 , 建立 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'
}
引入元件化後 ,
- 在 子產品化模式 中 , 需要導入
插件 , 子產品作為 依賴庫 使用 , 是 " Android Library " 類型的 Module 子產品 ;com.android.library
- 在 元件化模式 中 , 需要導入
插件 , 子產品作為 可執行應用 使用 , 是 " Phone & Tablet " 類型的 Module 子產品 ;com.android.application
通過在 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'
}