android data binding實踐之:源碼的正确打開姿勢
最近在深入學習android data binding庫,一邊寫demo,一邊看庫的源碼。但是在導入android data binding庫的時候卻遇到了各種麻煩。各種谷歌未果,最後折騰了一天終于找到了正确打開源碼的姿勢。這裡mark一下給同樣踩坑的人。
首先獻上data binding庫的源碼倉庫位址
git clone https://android.googlesource.com/platform/frameworks/data-binding
因為代碼是使用gradle進行編譯的,是以自己剛導入代碼的時候簡直就是心花怒放(相比那些使用maven、ant之類進行,gradle還是要來得更加親切的)。但是實際上,踩坑之旅這才剛剛開始。
謎之”version.gradle”
android studio剛導入代碼立馬就看到了下面的編譯錯誤:
Error:Could not read script ‘/Users/lemon/Documents/buildSrc/base/version.gradle’ as it does not exist.
我将源碼放在了 /Users/lemon/Documents/ 目錄下,但是這 version.gradle 究竟是何方神聖呢?使用全局搜尋很快就在propLoader.gradle 這個檔案中找到了引用,代碼節選如下:
// load android gradle plugin's version file
apply from: "${root}/../buildSrc/base/version.gradle"
databindingProperties.version = ext.buildVersion
// load version from gradle build file
apply from: "$root/../buildSrc/base/version.gradle"
databindingProperties.androidPluginVersion=ext.buildVersion
不難才想,在 version.gradle 當中其實就是定義了一些關于編譯環境的版本資訊的常量值。而這裡用到的常量值就隻有 buildVersion 這一個,我猜想這應該指的就是 android plugin version 。是以在這一個地方我們可以有兩個方案:
- 在項目根目錄下添加一個 version.gradle 檔案,并添加相應的變量定義,同時修改這裡的引用位址;
- 直接把這裡引用到的變量值替換成實際的常量值,并取消引入 version.gradle 這個檔案。
在這裡我選擇的是第二種做法,代碼如下:
//apply from: "$root/../buildSrc/base/version.gradle"
databindingProperties.androidPluginVersion='2.2.2'
// load android gradle plugin's version file
//apply from: "${root}/../buildSrc/base/version.gradle"
databindingProperties.version = '2.2.2'
你不會想到的”kotlin”出現了
修改完上面的檔案之後重新編譯,立馬又出現了新的問題,找不到”kotlin”的支援,因為庫當中有一個module compiler 使用了kotlin進行編寫的,是以你需要在android studio當中安裝kotlin插件,如下圖所示:
如果你認為安裝完插件之後就大功告成,那就真的是too young too simple了。重新編譯之後,讓人苦惱的想哭的編譯問題又出現了:
Error:Could not find org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.0-beta-4584.
…
Required by:
com.android.databinding:compiler:2.2.2
我們發現在 compiler 這個module編譯的時候,還需要一個 otlin-gradle-plugin 。我們打開 compiler 下的 build.gradle 檔案
apply plugin: 'java'
apply plugin: 'kotlin'
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
buildscript {
// to make IJ happy
ext.kotlin_version = dataBindingConfig.kotlinVersion
dependencies {
classpath 'commons-io:commons-io:2.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
dependencies {
compile project(':dataBinding:compilerCommon')
compile project(':dataBinding:baseLibrary')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.10'
compile 'com.tunnelvisionlabs:antlr4:4.5'
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
testCompile 'junit:junit:4.12'
}
是以我們需要給 compiler 添加上正确的依賴。從詳細的報錯資訊以及上面的配置我們會發現,項目并沒有從遠端倉庫去尋找依賴,而是從本地尋找的,是以我們得加上要使用的遠端倉庫聲明。另外,上面依賴的版本是通過 dataBindingConfig.kotlinVersion 定義的,為了減少修改,我直接把要使用的版本改成了最新的版本。具體修改之後的如下:
apply plugin: 'java'
apply plugin: 'kotlin'
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
buildscript {
repositories {
jcenter()
}
// to make IJ happy
// ext.kotlin_version = dataBindingConfig.kotlinVersion
dependencies {
classpath 'commons-io:commons-io:2.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2"
}
}
dependencies {
compile project(':dataBinding:compilerCommon')
compile project(':dataBinding:baseLibrary')
// compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.5-2"
compile 'commons-io:commons-io:2.4'
compile 'commons-codec:commons-codec:1.10'
compile 'org.antlr:antlr4:4.5.3'
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
testCompile 'junit:junit:4.12'
compile 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.5-2'
}
有一個要需要注意的是,我一開始使用的倉庫是 mavenCentral ,結果弄了好幾個小時都不能正确下載下傳,後來改成使用 jcenter 就好了。
經過上面的調整,然後美好的事情終于到來。data bindign這個庫終于可以順利編譯了,清晰的代碼目錄、代碼跳轉等等該有的都有了。感動到哭了有木有。
熱心提示
android data binding這個庫是經過多次修改的,其中如雙向綁定、lambada表達式這些是在gradle2.2 以後才會支援的,其他之前版本是沒有的。是以如果使用預設的master分支下的代碼,很抱歉,你會發現找不到相關的代碼。。。。。。(在某個早上,我折騰了好幾個小時,基本上把每個代碼檔案基本都翻了個遍,硬是沒找到應該有的代碼,在崩潰的邊緣,我都要開始相信玄學,認為谷歌又偷偷摸摸使用了一些不為人知的黑科技了)。
在遠端倉庫的網頁上,我們會發現除了很多的分支之外,還有很多的tag,如下圖所示:
不難猜到在 gradle_2.2.2 這個tag下面應該有我們想要的全部特性的代碼。是以在指令行下面,使用checkout指令就可以啦:
git checkout gradle_2.2.2
這下子終于可以愉快跟谷歌爸爸做朋友了。關于android data binding這個庫的具體分析歡迎關注我的部落格,接下來我會寫關于data binding這個庫的實踐的系列博文。