使用 kapt 时,Dagger 会跳过 Google 服务模块的工厂生成

Dagger skips Factory generation for Google Services module when using kapt

我有一个 Android 应用程序,我一直在将其转换为 Kotlin,并且在涉及特定模块时,我 运行 遇到了 Dagger 的障碍。

在我的项目build.gradle中,我有:

buildscript {
  ext.kotlin_version = "1.0.1-2"

  repositories {
    jcenter()
  }

  dependencies {
    classpath 'com.android.tools.build:gradle:2.1.0-alpha5'
    classpath 'com.google.gms:google-services:2.0.0-rc3'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  }
}

allprojects {
  repositories {
    jcenter()
  }
}

task clean(type: Delete) {
  delete rootProject.buildDir
}

并且在app/build.gradle中,我有以下相关设置:

apply plugin: "nebula.dependency-lock"
apply plugin: "com.android.application"
apply plugin: 'kotlin-android'
apply plugin: "kotlin-android-extensions"
apply plugin: "com.getkeepsafe.dexcount"

// ...

android {
  compileSdkVersion 23
  buildToolsVersion '23.0.2'

  // ...

  defaultConfig {
    applicationId "com.myapp"
    minSdkVersion 16
    targetSdkVersion 23
    // ...
  }

  buildTypes {
    debug {
      applicationIdSuffix ".debug"
      // ...
    }

    release {
      // ...
    }
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
    debug.java.srcDirs += 'src/debug/kotlin'
    release.java.srcDirs += 'src/release/kotlin'
    androidTest.java.srcDirs += 'src/androidTest/kotlin'
    test.java.srcDirs += 'src/test/kotlin'
  }
}

kapt {
  generateStubs = true
}

dependencies {
  compile fileTree(include: ["*.jar"], dir: "libs")

  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

  compile "com.google.android.gms:play-services-gcm:$playServicesVersion"
  compile "com.google.android.gms:play-services-analytics:$playServicesVersion"

  compile "com.google.dagger:dagger:$daggerVersion"
  kapt "com.google.dagger:dagger-compiler:$daggerVersion"
}

buildscript {
  ext.daggerVersion = "2.2"
  ext.playServicesVersion = "8.4.0"

  dependencies {
    classpath 'com.netflix.nebula:gradle-dependency-lock-plugin:4.2.0'
    classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.4.4'
    classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
  }

  repositories {
    mavenCentral()
  }
}

repositories {
  mavenCentral()
  jcenter()
  maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}

apply plugin: "com.google.gms.google-services"

我有一个应用程序组件:

@Singleton
@Component(
        modules = arrayOf(
                DebugApplicationModule::class,
                DataModule::class,
                DebugApiModule::class,
                GoogleApiModule::class,
                DebugSystemServicesModule::class
        )
)
interface ApplicationComponent : DebugApplicationGraph

GoogleApiModule:

@Module
@Singleton
class GoogleApiModule {
    @Provides
    @Singleton
    fun provideGoogleApiAvailability(): GoogleApiAvailability {
        return GoogleApiAvailability.getInstance()
    }

    @Provides
    @Singleton
    fun provideGcmRegistrationManager(
            context: Context,
            preferences: AppPreferences,
            googleApiAvailability: GoogleApiAvailability,
            apiService: ApiService): GCMRegistrationManager {

        return GCMRegistrationManager(context, preferences, googleApiAvailability, apiService)
    }

    @Provides
    @Singleton
    fun provideGoogleAnalytics(context: Context): GoogleAnalytics {
        val analytics = GoogleAnalytics.getInstance(context)
        analytics.setDryRun(BuildConfig.DEBUG)
        return analytics
    }

    @Provides
    @Singleton
    fun provideAnalyticsTracker(analytics: GoogleAnalytics): Tracker {
        val tracker = analytics.newTracker(BuildConfig.GOOGLE_ANALYTICS_TRACKING_ID)
        tracker.enableExceptionReporting(true)
        tracker.enableAutoActivityTracking(true)
        return tracker
    }
}

当我构建应用程序时,生成的`DaggerApplicationComponent 出现以下错误,说它找不到这些 类:

的符号

我的任何其他模块中似乎都没有任何其他错误(有很多),main 中该组件的所有其他模块似乎也能正常工作。

我不明白的是,是什么原因导致此模块无法为该模块构建工厂,而其他模块则无法构建,以及为什么它会如此悄无声息地失败。相同的结构在 Java 版本的应用程序中构建良好。

我已经尝试使用 provided 而不是 kapt 来实现 dagger-compiler,但这似乎完全跳过了 dagger 编译。

我已经尝试了任意数量的配置更改来使它正常工作,但我总是得到相同的结果。

有时,但并非总是如此,我也会在错误之前打印这条消息:

Note: Generating a MembersInjector for com.myapp.services.GCMMessageListenerService. 
Prefer to run the dagger processor over that class instead.

我不确定那是什么意思,我不确定它是否与缺少的编译有关,如果是的话我也不知道如何修复它。

正确:

  • kapt 配置设置正确
  • 您正在正确使用最新的 Dagger 2 和 Kotlin 版本。

要看的东西:

我想通了这个问题。在尝试将 GoogleApiModule 的不同部分分成不同的模块后,一个不同的模块被跳过,所以我调查了一下,发现两个不同的模块有相同的方法,但是 returning不同的类型并接受不同的参数。更改名称以免冲突解决了问题。

编辑:

我有另一个模块提供了一个依赖于 Google Analytics Tracker 的应用程序 Analytics Tracker。这两个不同的模块都有一个名为 provideAnalyticsTracker 的方法。他们有不同的方法签名和 return 类型,但是 kapt 在编译它时遇到了问题,尽管没有报告任何有意义的错误。使用 Java 的 Apt 可以处理命名冲突。