Koin注入到ViewModels android

问题描述

我决定从Dagger切换到Koin,因为它更轻巧,代码更少。 所以我有这样的模块

val databaseModule = module {

   single {
        get<AppDatabase>().serverDao()
    }
   
    // And all the DAOs here
}

val repositoryModule = module {

   single<ServerRepository> {
        // ServerDao,AccountDao,ApiManager
        return@single ServerRepositoryImpl(get(),get(),get())
    }

    // And all the repositories here

}

val networkModule = module {
    single<Gson> {
        val gsonBuilder = GsonBuilder()
        return@single gsonBuilder.setLenient().create()
    }

    single {
        if (!BuildConfig.DEBUG) return@single null

        val httpLoggingInterceptor = HttpLoggingInterceptor()
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        return@single httpLoggingInterceptor
    }

    single {
        return@single HeaderInterceptor()
    }

    single {
        return@single BaseUrlHolder(BuildConfig.BASE_HOLDER_URL)
    }

    single {
        val loggingInterceptor = get<Interceptor?>()
        OkHttpClient().newBuilder().apply {
            connectTimeout(60,TimeUnit.SECONDS)
            readTimeout(60,TimeUnit.SECONDS)
            writeTimeout(60,TimeUnit.SECONDS)
            loggingInterceptor?.let {
                addInterceptor(it)
            }
            addInterceptor(get<HeaderInterceptor>())
        }.also {
            return@single it.build()
        }
    }

    single<Retrofit> {
        return@single Retrofit.Builder()
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .addConverterFactory(GsonConverterFactory.create(get()))
            .client(get<OkHttpClient>())
            .build()
    }

    single<MyApiService> {
        return@single get<Retrofit>().create(MyApiService::class.java)
    }
}

val managersModule = module {
    single<ApiManager> {

        // I have to provide the URL runTime because it is not standar
        //  private val baseUrlHolder: BaseUrlHolder,//  private val retrofitBuilder: Retrofit.Builder
        return@single ApiManagerImpl(get(),get())
    }

所以在我的SplashView中,我想拥有ServerRepository和ApiManager。 我试图通过KoinComponent让它们通过,但一无所获

   // *****BaseViewModel implements KoinComponent*****
   class SplashViewModel : BaseViewModel() {

      // Here i should get the serverRepository.
      private val serverRepository: ServerRepository by inject()
      ......

   }

在SplashActivity中,我将viewmodel作为

private val splashViewModel: SplashViewModel by viewModels()

我总是遇到相同的错误

 Caused by: org.koin.core.error.NoBeanDefFoundException: No definition found for class:'retrofit2.Retrofit$Builder'. Check your definitions!

解决方法

必须定义ViewModel的Bean定义

val viewModelModule = module {
     viewModel {
         SplashViewModel() // if there are no parameter otherwise use get() function to pass the parameter of the viewmodel 
     }  
}
,

解决方案是我没有正确编写networkModule

single<OkHttpClient> {
        val loggingInterceptor = get<Interceptor?>()
        val httpClientBuilder = OkHttpClient().newBuilder().apply {
            connectTimeout(60,TimeUnit.SECONDS)
            readTimeout(60,TimeUnit.SECONDS)
            writeTimeout(60,TimeUnit.SECONDS)
            addInterceptor(get<HeaderInterceptor>())
            loggingInterceptor?.let {
                addInterceptor(loggingInterceptor)
            }
        }
        return@single httpClientBuilder.build()
    }

    single<Retrofit.Builder> {
        return@single Retrofit.Builder()
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .addConverterFactory(GsonConverterFactory.create(get()))
            .client(get<OkHttpClient>())
    }
,

您在这里询问Retrofit.Builder的实例

val managersModule = module {
    single<ApiManager> {

        // I have to provide the URL runTime because it is not standar
        //  private val baseUrlHolder: BaseUrlHolder,//  private val retrofitBuilder: Retrofit.Builder
        return@single ApiManagerImpl(get(),get())
    }

在依存关系图中,您仅提供Retrofit而不是Retrofit.Builder

以下几行中的更改可能会解决这种情况:

single<Retrofit.Builder> { // change type
        return@single Retrofit.Builder()
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .addConverterFactory(GsonConverterFactory.create(get()))
            .client(get<OkHttpClient>())
            // Remove
            //.build()
    }

single<MyApiService> {
        // adjustment
        return@single get<Retrofit.Builder>().build().create(MyApiService::class.java)
    }

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...