Android 如果没有@Provides方法,则无法提供名为的匕首2

Android 如果没有@Provides方法,则无法提供名为的匕首2,android,dependency-injection,kotlin,dagger-2,Android,Dependency Injection,Kotlin,Dagger 2,正在尝试摸索Dagger 2,但与指定的提供程序有问题。我有一个简单的设置,如下所示: // Module @Module class AppModule(private val app: App) { @Provides @AppScope fun providesApp() = app @Provides @AppScope fun provideSharedPreferences(app: App) = PreferenceManager.getDefaultShared

正在尝试摸索Dagger 2,但与指定的提供程序有问题。我有一个简单的设置,如下所示:

// Module
@Module
class AppModule(private val app: App) {
    @Provides @AppScope fun providesApp() = app

    @Provides @AppScope fun provideSharedPreferences(app: App) = PreferenceManager.getDefaultSharedPreferences(app)

    @Provides @AppScope @Named("Uri1") fun providesUri1() = Uri.Builder().scheme("https").authority("authory1").build()

    @Provides @AppScope @Named("Uri2") fun providesUri2() = Uri.Builder().scheme("https").authority("authory2").build()
}

// Component
@AppScope
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {
    fun inject(target: MainActivity)
}

// MainActivity
@Inject @AppScope lateinit var preferences: SharedPreferences
@Inject @AppScope @Named("Uri1") lateinit var uri1: Uri
@Inject @AppScope @Named("Uri2") lateinit var uri2: Uri
在重建我的项目时,我得到:

Error:Gradle: android.net.Uri cannot be provided without an @Provides- or @Produces-annotated method.
我不明白为什么在这里添加命名限定符对我不起作用。如果我删除这些,我可以得到一个SharedReferences的实例而不会出现问题

如果能了解我做错了什么,我们将不胜感激

编辑: 根据与上述结果相同的建议进行更改

// New module
@Module
class AppModule(private val app: App) {
    @Provides @AppScope fun providesApp() = app

    @Provides @AppScope fun provideSharedPreferences(app: App) = PreferenceManager.getDefaultSharedPreferences(app)

    @Provides @AppScope @Tag("Uri1") fun providesUri1(): Uri = Uri.Builder().scheme("https").authority("authority1").build()

    @Provides @AppScope @Tag("Uri2") fun providesUri2(): Uri = Uri.Builder().scheme("https").authority("authority2").build()
}

// Tag annotation
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class Tag(val tag: String = "")

// MainActivity
@Inject @AppScope lateinit var preferences: SharedPreferences
@Inject @AppScope @Tag("Uri1") lateinit var uri1: Uri
@Inject @AppScope @Tag("Uri2") lateinit var uri2: Uri

我想我找到了问题所在(至少我检查了你的项目,它正确地生成了dagger类)。如果您需要插入带有
@命名的
或某些
@限定符
注释的字段,则必须使用这种语法:

class MainActivity:AppCompatActivity(){
@注入lateinit变量首选项:SharedReferences
@注入@field:[Named(“Uri1”)]lateinit变量Uri1:Uri//用于@Named注释或。。。
@为@Qualifier注释注入@field:Uri2-lateinit变量Uri2:Uri/
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
app().component.inject(此)
println(uri1)
println(uri2)
}
}
注意
@Named
/qualifier注释如何进入
@字段:
(不带
@
本身)


借鉴了这个想法。

嗯,您的设置似乎很好。你能试试两样东西吗?1) 为您的
提供*
方法显式指定返回类型为
Uri
。2) 尝试使用限定符注释(自定义注释本身用
@qualifier
注释,并以与
@Named
相同的方式使用)而不是
@Named
,以区分uri。根据建议更改了@Androidx,请参阅编辑文章。到目前为止,结果没有差别!我以前从未在字段上见过示波器。尝试删除
@Inject@AppScope@Tag(“Uri1”)lateinit var Uri1:Uri中的作用域,否则我必须同意,它看起来很好我同意David关于作用域的看法。另外,您不需要设置保留,因为在kotlin中,默认情况下它是运行时,只需保存一行即可。我也从来没有使用过带有附加字段的限定符注释,例如,您可以创建
@Uri1
@Uri2
注释并使用它们……感谢您对David和Androidx的建议。不幸的是,同样的问题仍然存在。我已经在GitHub添加了一个指向测试项目repo的链接,如果更完整的上下文有帮助的话:。谢谢你搞定了!在你说这很有道理之后。谢谢你的努力!当前语法是
@Inject@AppScope@field:[Named(“Uri1”)]lateinit var Uri1:Uri
,而不是
@Inject@AppScope@field:[Uri1]lateinit var Uri1:Uri
,我想您描述的是另一种情况,如果
@Uri1
被注释为
@Qualifier
,那么我的语法是正确的。这只是一个示例,我没有指定是使用
@Qualifier
还是
@Named
注释,将此实现留给读者。这节省了我大量的时间!10x请注意:我认为在使用站点中不需要范围注释。@在我的情况下,AppScope注释不是必需的