Android動態改變工程依賴

app/build.gradle有以下庫依賴:api

dependencies {
    compile "com.xxx.yyy:somelib:$version"
}
複製代碼

如今若是要改爲源碼依賴(工程依賴)須要改2處地方: app/build.gradle:bash

dependencies {
    compile project(':somelib')
}
複製代碼

settings.gradle:app

include ':somelib'
project(":somelib").projectDir = new File("/lib/dir", "/some/path/somelib")
複製代碼

如今依賴的庫很是多, 並且還存在依賴嵌套, 但願只改一處配置就可以切換庫依賴與源碼依賴gradle

顯然用庫依賴settings.gradle裏不須要include那坨語句, 那麼必然須要在settings.gradle裏定義一個變量來做條件判斷, 這裏須要解決的一個核心問題是app/build.gradle可以訪問到settings.gradle裏的這個變量來繼續來做compile "com.xxx.yyy:somelib:$version"仍是compile project(':somelib')的判斷, 也就是須要一個***全局可訪問的gradle變量***ui

網上搜索了一圈居然沒找到!this

研究了一下發現如下重要2點:spa

  1. settings.gradle對象生成早於app/build.gradle甚至早於根目錄的build.gradle, 因此在build.gradle裏聲明ext { someVar=xxx }變量無效, settings沒法訪問
  2. app/build.gradle上下文依賴的project對象與settings.gradle共享同一個gradle對象

因而有以下配置: settings.gradle:code

def module_config = [
    'somelib': '',
    'aaa': '1.0.0',
    'bbb': '0.2.0',
    'ccc': '0.0.3',
]
module_config.each { k, v ->
    if (!v) {
        include ":${k}"
        project(":${k}").projectDir = new File(rootDir.getParent(), "/some/path/${k}")
    }
}
gradle.ext.dependon = { project, name ->
    def ver = module_config[name]
    def handler = project.dependencies
    if (!ver) {
        handler.compile project.project(":$name")
    } else {
        handler.compile "com.xxx.yyy:$name:$ver"
    }
}
複製代碼

這裏用gradle.ext定義了一個全局的方法而不是一個變量, 這樣在引用的時候直接調用: app/build.gradle:對象

dependencies {
    gradle.ext.dependon(this, "somelib")
    gradle.ext.dependon(this, "aaa")
    gradle.ext.dependon(this, "ccc")
}
複製代碼

這樣咱們只需更改module_config中對應模塊的版本就能夠實現一動態改變工程依賴的功能了!ci

注意gradle.ext.dependon傳入的是org.gradle.apiProject對象, 而project.dependencies是org.gradle.api.artifacts.dsl.DependencyHandler對象, 分別是gradle配置類

最根本最重要最核心的實際上是gradle.ext這個全局可訪問變量, 只要有了它徹底能夠用任何方式實現.

相關文章
相關標籤/搜索