Android 如果没有@Provides方法,则无法提供名为的匕首2
正在尝试摸索Dagger 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
// 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注释不是必需的