【问题标题】:Kotlin + Dagger2: cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated methodKotlin + Dagger2:不能在没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法的情况下提供
【发布时间】:2018-06-14 16:37:47
【问题描述】:

我收到以下错误:

错误:(8, 1) 错误:如果没有 @Inject 构造函数或 @Provides- 或 @Produces-annotated 方法,则无法提供 java.lang.String。

我一直在尝试制作一个提供两个合格字符串的模块。这是匕首的简化设置。

@Singleton
@Component(modules = [GreetingsModule::class])
interface AppComponent {
    fun inject(activity: MainActivity)
}

@Qualifier annotation class Spanish
@Qualifier annotation class French
@Qualifier annotation class English

@Module
@Singleton
class GreetingsModule {

    @Provides
    @Spanish
    fun providesHola(): String = "Hola mundo! - From Dagger"

    @Provides
    @English
    fun providesHello(): String = "Hello world! - From Dagger"

}

注入是在 MainActivity 中完成的:

class MainActivity : AppCompatActivity() {

    @Inject @Spanish
    lateinit var holaMundoText: String

    @Inject @English
    lateinit var helloWorldText: String

}

我也尝试直接在组件中声明 getter,但失败并出现同样的错误。将模块方法声明为静态时也是如此。

正如应该的那样,代码只使用一个@Provide 就可以正常工作,然后将字符串注入到两个字段中。我认为问题出在限定符上。

非常感谢任何帮助。


使用:

  • Android Studio 3.0.1
  • Kotlin 1.2.10
  • 匕首 2.14.1

【问题讨论】:

  • 您的GreetingsModule 中有@Provides @French 注释方法吗?
  • 哎呀,我从模块中删除了那个,但把它留在了活动中。我更新了帖子。谢谢
  • @crgarridos 您是否尝试仅使用问题中的代码进行编译?只是为了确保问题不在您的其余代码中。
  • @LordRaydenMK 是的,我只尝试使用此代码,最初它使用 DaggerAndroid 类。我删除了所有内容并手动离开。我已经花了超过 2 年的时间试图让它发挥作用。
  • @Onik 该模块不依赖任何东西,反正我试过了,得到了相同的 u.u

标签: android kotlin dagger-2 qualifiers


【解决方案1】:

使用 JSR-330 + Kotlin(Dagger2 是一个实现)在限定和命名注入方面存在一些问题。通过最近查看 Github 上 Dagger2 项目的积压工作,我知道 Google 团队希望在即将发布的版本中提供更主动的帮助/更有用的错误消息(无时间表)。

您缺少的是链接文档中所述的@field:<Qualifier> annotation use-type targets。所以试试吧;

@Inject @field:Spanish lateinit var holaMundoText: String

【讨论】:

  • 它就像一个亮点,你是一个救星。感谢您的解释+文档
  • 我花了一个小时试图找出问题所在,这个解决方案救了我,谢谢!
  • 所以这是为了使用限定符,使用命名注释呢?编辑:显然你可以使用这样的东西 @field:Named("aaa")
  • 更简洁的变体:\@field:[Inject Spanish] 而不是 \@Inject @field:Spanish
【解决方案2】:

我认为问题出在 Kotlin 编译器中,它不知道放置此类注释(参数、设置器、字段等)的位置。为了避免丑陋的@field:Spanish(西班牙语注释类被标记为限定符注释),我找到了另一个解决方案:只需使用带有适当参数的目标注释标记西班牙语注释,参见示例:

@Qualifier
@Target(FUNCTION, CONSTRUCTOR, FIELD, VALUE_PARAMETER, PROPERTY_SETTER)
annotation class Spanish

那么你可以使用:

@Inject @Spanish
lateinit var holaMundoText: String

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多