【问题标题】:Koin inject to viewModels androidKoin 注入到 viewModels android
【发布时间】:2020-08-13 16:08:33
【问题描述】:

我决定从 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 中,我将视图模型设为

private val splashViewModel: SplashViewModel by viewModels()

我总是遇到同样的错误

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

【问题讨论】:

    标签: android kotlin retrofit2 koin


    【解决方案1】:

    必须定义 ViewModel 的 Bean 定义

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

    【讨论】:

    • 不...同样的问题。我认为错误出在networkModule上。它说没有找到类的定义:'retrofit2.Retrofit$Builder'
    【解决方案2】:

    解决办法是我没有正确编写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>())
        }
    

    【讨论】:

      【解决方案3】:

      这里你问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)
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-23
        • 1970-01-01
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 2023-01-09
        相关资源
        最近更新 更多