迁移到AndroidX,Dagger2编译报java.util.NoSuchElementException

今天将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。
dagger2github 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

迁移到AndroidX,Dagger2编译报java.util.NoSuchElementException_第1张图片

jetifier-core-1.0.0-alpha10.jardefault.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" }
}

至此可以确认是因为Jetifier1.0.0-alpha10这个版本写死了dagger2的版本,从而导致在使用非2.16版本的dagger2的时候编译报[kapt] An exception occurred: java.util.NoSuchElementException异常。

所以解决这个问题有2个办法:

  1. dagger2的版本切换到2.16版本;
  2. 由于Jetifier1.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

你可能感兴趣的:(迁移到AndroidX,Dagger2编译报java.util.NoSuchElementException)