今天一早上班,拉了git上的最新代码正准备开始开发,gradle编译报如下错误:
ding.java:20: 错误: 找不到符号
protected ActivityCategoryBinding(DataBindingComponent _bindingComponent, View
_root,
^
符号: 类 DataBindingComponent
位置: 类 ActivityCategoryBinding
.....
e: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: failure, see logs for details.
Exception while handling step android.databinding.annotationprocessor.ProcessExpressions@3b33849b javax.xml.bind.UnmarshalException
- with linked exception:
[com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 3 字节的 UTF-8 序列的字节 3 无效。]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:204)
....
所有databinding 生成的binding 类都报了utf-8编码问题的错误,这个问题只会在win系统下会出现,在mac下没有此问题
为了排查这个问题,先百度了一圈,搜到的结果大部分是maven配置文件相关的信息,没有什么参考价值,猜测可能是Android Stdio、gradle、kapt、databinding 这四者之一出了问题,于是又去stackoverflow 带着这几个关键字和报错信息去查,找到了类似的问题,尝试了https://stackoverflow.com/questions/50594507/cannot-find-symbol-databindingcomponent-on-android-studio-3-2-canary-16-kotlin-p这个帖子里的一些回答,比如升级和更换gradle版本号、databinding版本 、在build.gradle文件指定utf-8编码的task、指定gradle的DEFAULT_JVM_OPTS为utf-8等方法均未解决
虽然走了一些弯路,不过也排除调了一些干扰项,产生这个bug的根源一定是出在databinding上,祭出终极手段:git回滚到上一个不报错的版本,比较layout文件夹下的所有改动,逐行修改编译,尝试是否编译成功,直到看到如下这行改动:
感觉不对,把这行更新到最新版本,编译报"3 字节的 UTF-8 序列的字节 3 无效"的错误,还原回上一个版本,编译正常
结论
‰这类特殊符号不属于utf-8编码,在win系统下databinding生成binding类存在bug会生成非utf-8编码的class文件从而导致所有binding类报错找不到符号,由于databinding编译时的报错信息无法定位到出错位置,手动排查十分麻烦,所以在layout文件中书写databinding时不要直接使用表达式拼接字符串,把固定文案都定义到string.xml文件里,尽可能避免此类问题。
国内关于databinding的资料目前非常少,写这篇文章希望能帮助到遇到同样错误的同学~
附录
当前的build.gradle配置项:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion compile_sdk_version
defaultConfig {
....
}
signingConfigs gradle.signingConfigs
buildTypes {
....
}
dataBinding {
enabled = true
}
}
kotlin {
experimental {
coroutines 'enable'
}
}
dependencies {
implementation 'com.android.support:multidex:1.0.3'
implementation fileTree(dir: 'libs', include: ['*.jar'])
//kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation "com.android.support.test.espresso:espresso-core:" + rootProject.espresso_version
implementation "com.android.support:support-v4:" + rootProject.supportLibVersion
implementation "com.android.support:palette-v7:" + rootProject.supportLibVersion
implementation "com.android.support:appcompat-v7:" + rootProject.supportLibVersion
implementation "com.android.support:design:" + rootProject.supportLibVersion
implementation "com.android.support:cardview-v7:" + rootProject.supportLibVersion
//ViewModel
implementation "android.arch.lifecycle:extensions:" + rootProject.archLifecycleVersion
implementation "android.arch.lifecycle:viewmodel:" + rootProject.archLifecycleVersion
kapt "android.arch.lifecycle:compiler:" + rootProject.archLifecycleVersion
//rx android
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.8'
....
}
buildscript {
ext.kotlin_version = '1.3.0'
ext.android_plugin_version = '3.2.1'
repositories {
jcenter()
google()
}
dependencies {
classpath "com.android.tools.build:gradle:$android_plugin_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}