Android 如何在koin中正确添加两个模块?

Android 如何在koin中正确添加两个模块?,android,kotlin,mvvm,dependency-injection,koin,Android,Kotlin,Mvvm,Dependency Injection,Koin,我正在开发一个新闻应用程序,我想在应用程序类中添加两个模块,但我得到以下例外 java.lang.RuntimeException: Unable to create application yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication: org.koin.core.error.DefinitionOverrideException: Already existing definition o

我正在开发一个新闻应用程序,我想在应用程序类中添加两个模块,但我得到以下例外

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.access$1300(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$1.invoke(SportNewsApplication.kt:19)
 at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate$1.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.kt类

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)
}
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)
}
const val BASE\u URL=”https://newsapi.org/"
val appModules=模块{
//将自定义HTTP客户端实例作为单例使用的改装服务
单身{
createWebService(
okHttpClient=createHttpClient(),
factory=RxJava2CallAdapterFactory.create(),
baseUrl=基本URL
)
}
//告诉Koin如何创建CatRepository的实例
工厂{(NewsRepositoryImpl(sportsNewsApi=get())}
//告诉Koin如何构建MainViewModel的特定viewModel模式
viewModel{MainViewModel(newsRepository=get())}
}
/*返回带有拦截器的自定义OkHttpClient实例。用于建筑物翻新服务*/
fun createHttpClient():OkHttpClient{
val client=OkHttpClient.Builder()
客户端读取超时(5*60,时间单位秒)
返回client.addInterceptor{
val original=it.request()
val requestBuilder=original.newBuilder()
header(“内容类型”、“应用程序/json”)
val request=requestBuilder.method(original.method,original.body.build())
return@addInterceptor继续(请求)
}.build()
}
/*功能,以建立我们的改装服务*/
内嵌式Web服务(
okHttpClient:okHttpClient,
工厂:CallAdapter.factory,baseUrl:String
):T{
val reformation=reformation.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create())
.addCallAdapterFactory(coroutineCalAdapterFactory())
.addCallAdapterFactory(工厂)
.客户(okHttpClient)
.build()
return reformation.create(T::class.java)
}
低于bbcModules.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)
}
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)
}
const val base\u url=”https://newsapi.org/"
val bbc模块=模块{
//将自定义HTTP客户端实例作为单例使用的改装服务
单身{
创建BBCWebService(
okHttpClient=CreateBchttpClient(),
factory=RxJava2CallAdapterFactory.create(),
baseUrl=基本url
)
}
//告诉Koin如何创建CatRepository的实例
工厂{(BBCRepositoryImpl(bbcsportNewsApi=get())}
//告诉Koin如何构建MainViewModel的特定viewModel模式
viewModel{BBCSportViewModel(bbcRepository=get())}
}
/*返回带有拦截器的自定义OkHttpClient实例。用于建筑物翻新服务*/
fun CreateBchttpClient():OkHttpClient{
val client=OkHttpClient.Builder()
客户端读取超时(5*60,时间单位秒)
返回client.addInterceptor{
val original=it.request()
val requestBuilder=original.newBuilder()
header(“内容类型”、“应用程序/json”)
val request=requestBuilder.method(original.method,original.body.build())
return@addInterceptor继续(请求)
}.build()
}
/*功能,以建立我们的改装服务*/
inline fun CreateBcWebService(
okHttpClient:okHttpClient,
工厂:CallAdapter.factory,baseUrl:String
):T{
val reformation=reformation.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create())
.addCallAdapterFactory(coroutineCalAdapterFactory())
.addCallAdapterFactory(工厂)
.客户(okHttpClient)
.build()
return reformation.create(T::class.java)
}
我试过的

1.清除重建并使缓存重新启动和其他堆栈溢出应答无效 这并没有解决我的问题

  • 我也遵循了以下链接

  • 我想知道如何解决异常。

    尝试使用
    命名
    。这是一个

    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.access$1300(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$1.invoke(SportNewsApplication.kt:19)
     at yodgorbek.komilov.musobaqayangiliklari.di.application.SportNewsApplication$onCreate$1.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
    
    下面是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)
    }
    
    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)
    }
    
    single(命名为(“appModules”)){
    创建BBCWebService(
    okHttpClient=CreateBchttpClient(),
    factory=RxJava2CallAdapterFactory.create(),
    baseUrl=基本url
    )
    }
    工厂{(NewsRepositoryImpl(sportsNewsApi=get(命名为(“appModules”)))}
    
    低于bbcModules.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)
    }
    
    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)
    }
    
    single(命名为(“bbcModules”)){
    创建BBCWebService(
    okHttpClient=CreateBchttpClient(),
    factory=RxJava2CallAdapterFactory.create(),
    baseUrl=基本url
    )
    }
    工厂{(BBCRepositoryImpl(bbcsportNewsApi=get(命名为(“bbcModules”)))}
    
    看起来您试图在单独的模块中创建两个OkHttpClient实例。您可以对模块使用override parametr以替代一个实例
    (模块(覆盖=true))
    但在这种情况下,这是不正确的。您必须有两个不同的实例OkHttpClient。为此,可以使用命名实例

    single<OkHttpClient>(named("WebService")) {
            createWebService<SportNewsInterface>(
                okHttpClient = createHttpClient(),
                factory = RxJava2CallAdapterFactory.create(),
                baseUrl = BASE_URL
            )
        }