如何在 koin 中正确添加两个模块?
How to add correctly two modules in koin?
我正在开发一个新闻应用程序,我想在应用程序中添加两个模块 class 但我收到以下异常。
java.lang.RuntimeException: Unable to create application yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one: [type:Single,primary_type:'yodgorbek.komilov.musobaqayangiliklari.internet.SportNewsInterface']
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5971)
at android.app.ActivityThread.access00(ActivityThread.java:206)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1700)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6820)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)
Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one: [type:Single,primary_type:'yodgorbek.komilov.musobaqayangiliklari.internet.SportNewsInterface']
at org.koin.core.registry.BeanRegistry.addDefinition(BeanRegistry.kt:144)
at org.koin.core.registry.BeanRegistry.saveDefinition(BeanRegistry.kt:101)
at org.koin.core.registry.BeanRegistry.saveDefinitions(BeanRegistry.kt:71)
at org.koin.core.registry.BeanRegistry.loadModules(BeanRegistry.kt:49)
at org.koin.core.KoinApplication.loadModulesAndScopes(KoinApplication.kt:66)
at org.koin.core.KoinApplication.modules(KoinApplication.kt:60)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate.invoke(SportNewsApplication.kt:19)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate.invoke(SportNewsApplication.kt:11)
at org.koin.core.context.GlobalContextKt.startKoin(GlobalContext.kt:72)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication.onCreate(SportNewsApplication.kt:16)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1155)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5966)
... 8 more
低于SportNewsApplication.ktclass
class SportNewsApplication : Application() {
override fun onCreate() {
super.onCreate()
// Adding Koin modules to our application
startKoin {
// androidContext(this@SportNewsApplication)
modules(
listOf(appModules, bbcModules))
}
}
}
低于appModules.kt
const val BASE_URL = "https://newsapi.org/"
val appModules = module {
// The Retrofit service using our custom HTTP client instance as a singleton
single {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
// Tells Koin how to create an instance of CatRepository
factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get())) }
// Specific viewModel pattern to tell Koin how to build MainViewModel
viewModel { MainViewModel(newsRepository = get()) }
}
/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
val client = OkHttpClient.Builder()
client.readTimeout(5 * 60, TimeUnit.SECONDS)
return client.addInterceptor {
val original = it.request()
val requestBuilder = original.newBuilder()
requestBuilder.header("Content-Type", "application/json")
val request = requestBuilder.method(original.method, original.body).build()
return@addInterceptor it.proceed(request)
}.build()
}
/* function to build our Retrofit service */
inline fun <reified T> createWebService(
okHttpClient: OkHttpClient,
factory: CallAdapter.Factory, baseUrl: String
): T {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addCallAdapterFactory(factory)
.client(okHttpClient)
.build()
return retrofit.create(T::class.java)
}
低于bbcModules.kt
const val base_url = "https://newsapi.org/"
val bbcModules = module {
// The Retrofit service using our custom HTTP client instance as a singleton
single {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
// Tells Koin how to create an instance of CatRepository
factory<BBCRepository> { (BBCRepositoryImpl(bbcsportNewsApi = get())) }
// Specific viewModel pattern to tell Koin how to build MainViewModel
viewModel { BBCSportViewModel(bbcRepository = get()) }
}
/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createBBCHttpClient(): OkHttpClient {
val client = OkHttpClient.Builder()
client.readTimeout(5 * 60, TimeUnit.SECONDS)
return client.addInterceptor {
val original = it.request()
val requestBuilder = original.newBuilder()
requestBuilder.header("Content-Type", "application/json")
val request = requestBuilder.method(original.method, original.body).build()
return@addInterceptor it.proceed(request)
}.build()
}
/* function to build our Retrofit service */
inline fun <reified T> createBBCWebService(
okHttpClient: OkHttpClient,
factory: CallAdapter.Factory, baseUrl: String
): T {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addCallAdapterFactory(factory)
.client(okHttpClient)
.build()
return retrofit.create(T::class.java)
}
我试过的
1.clean 重建并使缓存失效重启和其他 Whosebug 答案
它没有解决我的问题。
我想知道我必须做什么才能解决异常。
尝试使用named
。这是一个doc
低于 appModules.kt
single(named("appModules")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get(named("appModules")))) }
低于bbcModules.kt
single(named("bbcModules")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
factory<BBCRepository> { (BBCRepositoryImpl(bbcsportNewsApi = get(named("bbcModules")))) }
您似乎试图在不同的模块中创建两个 OkHttpClient 实例。您可以使用模块的覆盖参数来覆盖另一个实例
(module(override = true))
但在这种情况下,这是不正确的。你必须有两个不同的实例 OkHttpClient。为此,您可以使用命名实例
single<OkHttpClient>(named("WebService")) {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
和
single<OkHttpClient>(named("BBCWebService")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
如果需要注入特定客户端需要使用
SomeClassNeedDependency(get(named("WebService")))
我正在开发一个新闻应用程序,我想在应用程序中添加两个模块 class 但我收到以下异常。
java.lang.RuntimeException: Unable to create application yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one: [type:Single,primary_type:'yodgorbek.komilov.musobaqayangiliklari.internet.SportNewsInterface']
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5971)
at android.app.ActivityThread.access00(ActivityThread.java:206)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1700)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6820)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)
Caused by: org.koin.core.error.DefinitionOverrideException: Already existing definition or try to override an existing one: [type:Single,primary_type:'yodgorbek.komilov.musobaqayangiliklari.internet.SportNewsInterface']
at org.koin.core.registry.BeanRegistry.addDefinition(BeanRegistry.kt:144)
at org.koin.core.registry.BeanRegistry.saveDefinition(BeanRegistry.kt:101)
at org.koin.core.registry.BeanRegistry.saveDefinitions(BeanRegistry.kt:71)
at org.koin.core.registry.BeanRegistry.loadModules(BeanRegistry.kt:49)
at org.koin.core.KoinApplication.loadModulesAndScopes(KoinApplication.kt:66)
at org.koin.core.KoinApplication.modules(KoinApplication.kt:60)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate.invoke(SportNewsApplication.kt:19)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate.invoke(SportNewsApplication.kt:11)
at org.koin.core.context.GlobalContextKt.startKoin(GlobalContext.kt:72)
at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication.onCreate(SportNewsApplication.kt:16)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1155)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5966)
... 8 more
低于SportNewsApplication.ktclass
class SportNewsApplication : Application() {
override fun onCreate() {
super.onCreate()
// Adding Koin modules to our application
startKoin {
// androidContext(this@SportNewsApplication)
modules(
listOf(appModules, bbcModules))
}
}
}
低于appModules.kt
const val BASE_URL = "https://newsapi.org/"
val appModules = module {
// The Retrofit service using our custom HTTP client instance as a singleton
single {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
// Tells Koin how to create an instance of CatRepository
factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get())) }
// Specific viewModel pattern to tell Koin how to build MainViewModel
viewModel { MainViewModel(newsRepository = get()) }
}
/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createHttpClient(): OkHttpClient {
val client = OkHttpClient.Builder()
client.readTimeout(5 * 60, TimeUnit.SECONDS)
return client.addInterceptor {
val original = it.request()
val requestBuilder = original.newBuilder()
requestBuilder.header("Content-Type", "application/json")
val request = requestBuilder.method(original.method, original.body).build()
return@addInterceptor it.proceed(request)
}.build()
}
/* function to build our Retrofit service */
inline fun <reified T> createWebService(
okHttpClient: OkHttpClient,
factory: CallAdapter.Factory, baseUrl: String
): T {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addCallAdapterFactory(factory)
.client(okHttpClient)
.build()
return retrofit.create(T::class.java)
}
低于bbcModules.kt
const val base_url = "https://newsapi.org/"
val bbcModules = module {
// The Retrofit service using our custom HTTP client instance as a singleton
single {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
// Tells Koin how to create an instance of CatRepository
factory<BBCRepository> { (BBCRepositoryImpl(bbcsportNewsApi = get())) }
// Specific viewModel pattern to tell Koin how to build MainViewModel
viewModel { BBCSportViewModel(bbcRepository = get()) }
}
/* Returns a custom OkHttpClient instance with interceptor. Used for building Retrofit service */
fun createBBCHttpClient(): OkHttpClient {
val client = OkHttpClient.Builder()
client.readTimeout(5 * 60, TimeUnit.SECONDS)
return client.addInterceptor {
val original = it.request()
val requestBuilder = original.newBuilder()
requestBuilder.header("Content-Type", "application/json")
val request = requestBuilder.method(original.method, original.body).build()
return@addInterceptor it.proceed(request)
}.build()
}
/* function to build our Retrofit service */
inline fun <reified T> createBBCWebService(
okHttpClient: OkHttpClient,
factory: CallAdapter.Factory, baseUrl: String
): T {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addCallAdapterFactory(factory)
.client(okHttpClient)
.build()
return retrofit.create(T::class.java)
}
我试过的
1.clean 重建并使缓存失效重启和其他 Whosebug 答案 它没有解决我的问题。
我想知道我必须做什么才能解决异常。
尝试使用named
。这是一个doc
低于 appModules.kt
single(named("appModules")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
factory<NewsRepository> { (NewsRepositoryImpl(sportsNewsApi = get(named("appModules")))) }
低于bbcModules.kt
single(named("bbcModules")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
factory<BBCRepository> { (BBCRepositoryImpl(bbcsportNewsApi = get(named("bbcModules")))) }
您似乎试图在不同的模块中创建两个 OkHttpClient 实例。您可以使用模块的覆盖参数来覆盖另一个实例
(module(override = true))
但在这种情况下,这是不正确的。你必须有两个不同的实例 OkHttpClient。为此,您可以使用命名实例
single<OkHttpClient>(named("WebService")) {
createWebService<SportNewsInterface>(
okHttpClient = createHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = BASE_URL
)
}
和
single<OkHttpClient>(named("BBCWebService")) {
createBBCWebService<SportNewsInterface>(
okHttpClient = createBBCHttpClient(),
factory = RxJava2CallAdapterFactory.create(),
baseUrl = base_url
)
}
如果需要注入特定客户端需要使用
SomeClassNeedDependency(get(named("WebService")))