前言
本文涉及的問題的前提是使用了DataBinding+Room,如果讀者正好也使用這兩個框架,請往后閱讀。如果未使用Room也出錯,建議仔細檢查最近編輯的xml是否存在不規(guī)范的地方。
環(huán)境
Android Studio 3.2
compileSdkVersion 28
com.android.support:28.0.0
android.arch.persistence.room:1.1.1
"com.android.tools.build:gradle:3.2.1"
之所以強調(diào)環(huán)境,是因為在未升級AS到3.2和未適配Api 28之前不曾出現(xiàn)該錯誤。
掉坑
哥們兒正愉快飛速地擼碼,感覺可以看看效果了,特么突然就崩了。(╯‵□′)╯︵┻━┻(冷靜5秒后,開始找錯)
該錯誤出現(xiàn)在編譯時,任務(wù):app:kaptDebugKotlin報錯,報錯輸出:
Compilation error. See log for more details
只看這里是懵逼的。再看指向出錯的類,發(fā)現(xiàn)全部與DataBinding相關(guān)的類全部報錯!頓感大事不妙啊!還讓人怎么玩啊!點開任何一個出錯類,紅色log均顯示:
錯誤: 找不到符號 protected ***Binding(DataBindingComponent _bindingComponent, View _root,
符號: 類 DataBindingComponent
位置: 類 ***Binding
英文環(huán)境大概是這樣:
error: cannot find symbol protected ***Binding(DataBindingComponent _bindingComponent, View _root,
symbol: class DataBindingComponent
location: class ***Binding
這里“***Binding”代表DataBinding自動生成的類,比如在我的項目里ActivityMainBinding:

此時由懵逼逐漸驚慌失措。
爬坑
咱們遇到陌生的bug第一件事當然是Google一下,StackOverflow的答案安排地明明白白。然而,一小時過去了,網(wǎng)上所有的方案都試過了,甚至懷疑電腦中暑了給重啟了一下,錯誤依舊。白頭搔更短,渾欲不勝簪!
片刻冷靜過后,分析問題:錯誤是我編輯代碼后出現(xiàn)的,說明bug是隱藏在變更的地方。因此,我開始一行行檢查修改處的代碼,尤其是xml里使用DataBinding有無語法錯誤,對懷疑之處進行注釋或替換。運行,依然報錯。走投無路,只好祭出終極大法——還原法——逐一還原修改后的代碼至未出錯時的節(jié)點,一邊還原一邊編譯運行,直到運行成功,bug自然水落石出。
填坑(全網(wǎng)首發(fā))
這個坑是Room刨的!
原來所有的數(shù)據(jù)表的主鍵字段(以@PrimaryKey標注),如果它自身可被賦值為null(如String),則必須用@NonNull標注。例如:
@Entity(tableName = "users")
public class UserEntity {
@PrimaryKey
@NonNull // required
private String id;
@NonNull
public String getId() {
return id;
}
public void setId(@NonNull String id) {
this.id = id;
}
}
否則Room在編譯時會檢查不通過,隨之引起DataBinding編譯失敗,從而報了這個坑爹的錯誤。這次DataBinding差點當了背鍋俠。
后記
萬萬沒想到區(qū)區(qū)一行標注差點引起我對人生的思考,也萬萬沒想到我能一行一行地debug把它找出來。之前在Api 27環(huán)境下并不會報錯,不知道谷爹將來會不會修正,或者給個明確提示也行啊。寫這篇爬坑日記的原因,一來自己Google后也未能找到正確的解決辦法,正好來個填坑(全球)首發(fā),如果正好幫到困惑的讀者,善莫大焉。二來作一番爬坑經(jīng)驗的分享和交流。