1邻薯、組件化思路
“聚合和解耦是項(xiàng)目架構(gòu)的基礎(chǔ)”裙戏,站在組件化項(xiàng)目角度,第一步期望子組件可以作為APP單獨(dú)調(diào)試和殼APP集成發(fā)布厕诡。好處在于開發(fā)者在一個(gè)子項(xiàng)目中把子組件作為一個(gè)子app開發(fā)累榜,而不影響別人。APP上線灵嫌,發(fā)布者只需關(guān)心是否合并子組件功能信柿。
2、單獨(dú)調(diào)試與集成發(fā)布需求拆解
- 1醒第、單獨(dú)調(diào)試:指通過(guò)一個(gè)標(biāo)志isRunAlone, 若isRunAlone==true,當(dāng)前l(fā)ib項(xiàng)目轉(zhuǎn)化為app項(xiàng)目渔嚷,反之為lib項(xiàng)目,移除調(diào)試代碼
- 2稠曼、集成發(fā)布:指殼工程形病,IDE編寫代碼時(shí),不能引用子組件代碼霞幅,做到編寫隔離漠吻,而編譯時(shí),又要將子組件代碼編譯到主項(xiàng)目中司恳,最好配置是在殼工程中g(shù)radle.propetties途乃,建議也要支持?jǐn)U展方法addComponent,以函數(shù)方式支持
3扔傅、核心邏輯
- 1耍共、初始化當(dāng)前項(xiàng)目
- 2、獲取當(dāng)前任務(wù)類型
- 3猎塞、若當(dāng)前是殼工程试读,支持編譯隔離
- 4、若當(dāng)前是子組件荠耽,支持單獨(dú)調(diào)試和發(fā)布
3.1 示例代碼
void apply(Project project) {
this.mProject = project
//1钩骇、初始化當(dāng)前項(xiàng)目
initAlone(project)
//2、判斷當(dāng)前任務(wù) 只有assemble任務(wù)才添加依賴
assembleTask = getTaskInfo(project)
//3铝量、當(dāng)前是殼工程 不許被引用
if (isMainApp(project)) {
//運(yùn)行殼工程配置
runMainApp(project)
//添加配置依賴
compileComponents(assembleTask, project)
//添加擴(kuò)展方法 (選項(xiàng)) 參數(shù)
project.ext.addComponent = { dependencyName -> addComponent(dependencyName) }
return
}
//4倘屹、支持單獨(dú)調(diào)試和發(fā)布
runAlone(project)
}
3.2單獨(dú)調(diào)試
private static final String DEBUG_DIR = "src/main/debug/"
/**
* 支持單獨(dú)調(diào)試和發(fā)布
*/
private void runAlone(Project project) {
//1.找當(dāng)前module的狀態(tài)
boolean isRunAlone = fetchAloneStatus(project)
if (isRunAlone) {
project.apply plugin: 'com.android.application'
log("apply plugin is " + 'com.android.application')
project.android.sourceSets {
main {
//debug模式下,如果存在src/main/debug/AndroidManifest.xml慢叨,則自動(dòng)使用其作為manifest文件
def debugManifest = "${DEBUG_DIR}AndroidManifest.xml"
if (project.file(debugManifest).exists()) {
manifest.srcFile debugManifest
}
java.srcDirs = ['src/main/java', "${DEBUG_DIR}java"]
res.srcDirs = ['src/main/res', "${DEBUG_DIR}res"]
assets.srcDirs = ['src/main/assets', "${DEBUG_DIR}assets"]
jniLibs.srcDirs = ['src/main/jniLibs', "${DEBUG_DIR}jniLibs"]
}
}
} else {
project.apply plugin: 'com.android.library'
log("apply plugin is " + 'com.android.library')
//main下刪除所有debug目錄下的文件
project.android.sourceSets.main {
//默認(rèn)這個(gè)位置纽匙,為代碼清晰
manifest.srcFile 'src/main/AndroidManifest.xml'
//刪除所有debug目錄下內(nèi)容
java {
exclude 'debug/**'
}
res {
exclude 'debug/**'
}
assets {
exclude 'debug/**'
}
jniLibs {
exclude 'debug/**'
}
}
}
}
4、插件編寫原則
1插爹、單一職責(zé):一個(gè)插件只做好一件事哄辣,不要與其他組件化插件功能耦合请梢。
2赠尾、配置化:用戶最小情況修改代碼力穗,可以帶來(lái)穩(wěn)定
3、易用性:以用戶為中心气嫁,編寫代碼提供插件支持当窗,減少生僻概念,支持用戶慣性寫法
1寸宵、單一職責(zé)
單獨(dú)調(diào)試和集成發(fā)布功能屬于通用功能崖面,即使不做插件化,在開發(fā)中也有好處梯影。過(guò)于強(qiáng)大插件功能巫员,易用性反而降低,進(jìn)而限制了2甲棍、配置化
在根目錄下gradle.propetties配置isRunAlone简识,就可以設(shè)置設(shè)置項(xiàng)目中組件lib與app形式切換
在空殼app下gradle.propetties配置,就可以動(dòng)態(tài)引入子組件
###是否為主APP
isMainApp=true
###配置方式接入組件
debugComponent=':module_main',\
':module_girls',\
':module_news'
releaseComponent=':module_main',\
':module_girls',\
':module_news'
- 易用性 支持殼工程 addComponent(':module_main')函數(shù),在gradle中引入子組件,配置還支持容錯(cuò)性trimAll不可見字符
5感猛、使用示例
根目錄配置gradle.propetties
##集成與獨(dú)立模式
isRunAlone=false
1七扰、殼工程
gradle配置
apply plugin: 'thorAlone'
并且刪除原來(lái)的app引用
//apply plugin: 'com.android.application'
//或采用這種方式
dependencies{
//組件解耦采用這種方式 assemble 才會(huì)引入依賴 build并不引入達(dá)到組件間代碼隔離
addComponent(':module_main')
addComponent(deps.support.multidex)
}
gradle.propetties
###是否為主APP
isMainApp=true
###配置方式接入組件
debugComponent=':module_main',\
':module_girls',\
':module_news'
releaseComponent=':module_main',\
':module_girls',\
':module_news'
2、子組件配置
gradle配置,刪除sourceSets
apply plugin: 'thorAlone'
并且刪除原來(lái)的lib引用
//apply plugin: 'com.android.library'
//刪除 sourceSets
//sourceSets{
//main{}
//}
子組件代碼配置
6陪白、項(xiàng)目代碼
https://github.com/yinlingchaoliu/AndroidComponent
插件位置
AndroidComponent/thor_alone_gradle_plugin
//諸神黃昏
include ':component:thor_alone_gradle_plugin',