前言
本文涉及的问题的前提是使用了DataBinding
+Room
,如果读者正好也使用这两个框架,请往后阅读。如果未使用Room
也出错,建议仔细检查最近编辑的xml是否存在不规范的地方。
环境
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"
之所以强调环境,是因为在未升级AS到3.2和未适配Api 28之前不曾出现该错误。
掉坑
哥们儿正愉快飞速地撸码,感觉可以看看效果了,特么突然就崩了。(╯‵□′)╯︵┻━┻(冷静5秒后,开始找错)
该错误出现在编译时,任务:app:kaptDebugKotlin
报错,报错输出:
Compilation error. See log for more details
只看这里是懵逼的。再看指向出错的类,发现全部与DataBinding
相关的类全部报错!顿感大事不妙啊!还让人怎么玩啊!点开任何一个出错类,红色log均显示:
错误: 找不到符号 protected ***Binding(DataBindingComponent _bindingComponent, View _root,
符号: 类 DataBindingComponent
位置: 类 ***Binding
英文环境大概是这样:
error: cannot find symbol protected ***Binding(DataBindingComponent _bindingComponent, View _root,
symbol: class DataBindingComponent
location: class ***Binding
这里“***Binding”代表DataBinding
自动生成的类,比如在我的项目里ActivityMainBinding
:
此时由懵逼逐渐惊慌失措。
爬坑
咱们遇到陌生的bug第一件事当然是Google一下,StackOverflow的答案安排地明明白白。然而,一小时过去了,网上所有的方案都试过了,甚至怀疑电脑中暑了给重启了一下,错误依旧。白头搔更短,浑欲不胜簪!
片刻冷静过后,分析问题:错误是我编辑代码后出现的,说明bug是隐藏在变更的地方。因此,我开始一行行检查修改处的代码,尤其是xml里使用DataBinding
有无语法错误,对怀疑之处进行注释或替换。运行,依然报错。走投无路,只好祭出终极大法——还原法——逐一还原修改后的代码至未出错时的节点,一边还原一边编译运行,直到运行成功,bug自然水落石出。
填坑(全网首发)
这个坑是Room
刨的!
原来所有的数据表的主键字段(以@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
差点当了背锅侠。
后记
万万没想到区区一行标注差点引起我对人生的思考,也万万没想到我能一行一行地debug把它找出来。之前在Api 27环境下并不会报错,不知道谷爹将来会不会修正,或者给个明确提示也行啊。写这篇爬坑日记的原因,一来自己Google后也未能找到正确的解决办法,正好来个填坑(全球)首发,如果正好帮到困惑的读者,善莫大焉。二来作一番爬坑经验的分享和交流。