今天将android
依赖升级到AndroidX
后,编译失败,并报如下异常信息:
e: [kapt] An exception occurred: java.util.NoSuchElementException
由于没有更多异常信息,并且我的demo
是个新建的空工程,还没有写Dagger2
相关的代码,所以开始猜测可能是dagger2
的依赖有问题。
build.gradle
中依赖配置如下:
ext.dagger_version = 2.19
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha06'
implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha06'
implementation 'android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha06'
implementation 'android.arch.navigation:navigation-ui-ktx:1.0.0-alpha06'
implementation 'androidx.core:core-ktx:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
implementation 'com.google.android.material:material:1.0.0-beta01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version" // if you use the support libraries
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
}
根据dagger2
的文档检查了几遍之后,确认自己的依赖没有问题,所以只能求助于万能Google。
在dagger2
的github Issues
下发现了其他开发者提出的问题:Dagger-2.17 An exception occurred: java.util.NoSuchElementException
在该问题下有人反馈该问题是Jetifier
的配置导致的:
在给出的
Jetifier
的配置文件中有如下配置:原来在
Jetifier
的某个版本中,将Dagger2
的依赖写死成2.16
了,所以如果使用了这个版本的Jetifer
,而Dagger2
的版本不是2.16
,就会出现标题中异常信息;而我前面配置中dagger2
的版本是2.19
,所以就出现了标题中异常信息。我们接下来验证下
Jetifier
的版本,那么怎么看Jetifer
的版本呢?首先回顾下是如何迁移
AndroidX
和启用Jetifer
配置的?根据官方的Migrating to AndroidX文档说明,需要在工程的gradle.properties配置中增加如下配置:
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
所以Jetifier
是已经被Android Studio
内置了,我们需要到Android Studio
的安装目录下去找Jetifier
的默认版本,
在Android Studio
下的gradle\m2repository\com\android\tools\build\jetifier\jetifier-core
目录下发现了Jetifier
的版本:1.0.0-alpha10
在
jetifier-core-1.0.0-alpha10.jar
的default.config
文件中发现了如下配置:
# Androidx compatible dagger
{
"from": { "groupId": "com.google.dagger", "artifactId": "dagger-android-processor", "version": "2.16" },
"to": { "groupId": "com.google.dagger", "artifactId": "dagger-android-processor", "version": "2.16" }
}
至此可以确认是因为Jetifier
的1.0.0-alpha10
这个版本写死了dagger2
的版本,从而导致在使用非2.16
版本的dagger2
的时候编译报[kapt] An exception occurred: java.util.NoSuchElementException
异常。
所以解决这个问题有2个办法:
- 将
dagger2
的版本切换到2.16
版本;- 由于
Jetifier
在1.0.0-beta01
版本已经修复了该问题,所以将Jetifier
升级到1.0.0-beta01
或者更高的版本;
注:在工程的build.gradle
中添加classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
配置,即可将Jetifier
升级到1.0.0-beta02
经验证,上面2种办法都可以解决编译报java.util.NoSuchElementException
的问题
参考链接:
https://github.com/google/dagger/issues/1245
https://android.googlesource.com/platform/frameworks/support/+/f5b4ca1da3ffc38b1701aa64597716e3071bf136/jetifier/jetifier/core/src/main/resources/default.config#1392