Dagger2-Retrofit не вводит в ApiHelperImpl

Привет, я пытаюсь внедрить retrofit в классе ApiHelperImpl.kt . У меня есть модуль и компонент.

AppComponent.kt

 @Component(modules = arrayOf(AndroidInjectionModule::class, AppModule::class, ActivityBuilder::class)) @Singleton interface AppComponent { fun inject(app: PartnerApplication) } 

AppModule.kt

 @Module class AppModule { @Provides @Singleton fun providesPartnerApplication(application: Application): Application = application @Provides @Singleton fun providesSharedPreferences(application: Application): SharedPreferences { return PreferenceManager.getDefaultSharedPreferences(application) } @Provides @Singleton fun provideOkHttpCache(application: Application): Cache { val cacheSize = 10 * 1024 * 1024L // 10 MiB return Cache(application.cacheDir, cacheSize) } @Provides @Singleton fun provideMoshi(): Moshi = Moshi.Builder().build() @Provides @Singleton fun provideOkHttpClient(cache: Cache): OkHttpClient { val okHttpClient = OkHttpClient() okHttpClient.newBuilder() .cache(cache) .build() return okHttpClient } @Provides @Singleton fun provideRetrofit(moshi: Moshi, okHttpClient: OkHttpClient): Retrofit { return Retrofit.Builder() .addConverterFactory(MoshiConverterFactory.create(moshi)) .baseUrl(BuildConfig.BASE_URL) .client(okHttpClient) .build() } } 

PartnerApplication.kt

 class PartnerApplication : Application(), AnkoLogger, HasActivityInjector { @Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity> override fun activityInjector(): AndroidInjector<Activity> { return activityInjector } override fun onCreate() { super.onCreate() DaggerAppComponent.create().inject(this) } override protected fun attachBaseContext(base: Context) { super.attachBaseContext(base) MultiDex.install(this) } } 

ApiHelper.kt

 interface ApiHelper { fun doServerLoginApiCall(email: String, password: String): Observable<LoginResponse> fun doServerRegistrationApiCall(): Observable<RegistrationResponse> } 

ApiHelperImpl.kt

 class ApiHelperImpl : ApiHelper { @Inject lateinit var retrofit: Retrofit override fun doServerLoginApiCall(email: String, password: String): Observable<LoginResponse> { return retrofit.create(RestApi::class.java).login(email, password) } override fun doServerRegistrationApiCall(): Observable<RegistrationResponse> { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } } 

LoginActivity.kt

 class LoginActivity : BaseActivity() { @Inject lateinit var loginViewModel: LoginViewModel override fun onCreate(savedInstanceState: Bundle?) { performDependencyInjection() super.onCreate(savedInstanceState) val activityLoginBinding: ActivityLoginBinding = DataBindingUtil.setContentView<ActivityLoginBinding>(this, R.layout.activity_login) activityLoginBinding.loginViewModel = loginViewModel } } 

LoginViewModel.kt

 class LoginViewModel : ViewModel(), AnkoLogger { val emailField = ObservableField<String>() private val email: String get() = emailField.get() val passwordField = ObservableField<String>() private val password: String get() = passwordField.get() val progressVisibility: ObservableInt = ObservableInt(View.GONE) @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") fun login(view: View) { if (isEmailAndPasswordValid(email, password)) ApiHelperImpl().doServerLoginApiCall(email, password) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(object : CallbackWrapper<LoginResponse>() { override fun onSuccess(loginResponse: LoginResponse) { } }) } /** * Validate email and password. It checks email and password is empty or not * and validate email address is correct or not * @param email email address for login * @param password password for login * @return true if email and password pass all conditions else false */ private fun isEmailAndPasswordValid(email: String, password: String): Boolean { if (email.isEmpty()) return false if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) return false if (password.isEmpty()) return false return true } } 

LoginActivityModule.kt

 @Module class LoginActivityModule { @Provides fun providesLoginActivityViewModel(): LoginViewModel { return LoginViewModel() } } 

ActivityBuilder.kt

 @Module abstract class ActivityBuilder { @ContributesAndroidInjector(modules = arrayOf(LoginActivityModule::class)) abstract fun bindLoginActivity(): LoginActivity } 

Я получаю сообщение об ошибке

 Process: com.partner.android, PID: 9697 kotlin.UninitializedPropertyAccessException: lateinit property retrofit has not been initialized at com.partner.android.data.remote.ApiHelperImpl.doServerLoginApiCall(ApiHelperImpl.kt:32) at com.partner.android.login.LoginViewModel.login(LoginViewModel.kt:45) at com.partner.android.databinding.ActivityLoginBinding$OnClickListenerImpl.onClick(ActivityLoginBinding.java:298) at android.view.View.performClick(View.java:5637) at android.view.View$PerformClick.run(View.java:22429) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

Почему retrofit не вводится в класс ApiHelperImpl.

чтобы использовать @Inject в ApiHelperImpl вам нужно добавить его (вызывать inject на компоненте) на граф зависимостей. В этом случае я ApiHelperImpl его как зависимость от конструктора ApiHelperImpl

  class ApiHelperImpl @Inject constructor(val retrofit : Retrofit) : ApiHelper { val mRetrofit = retrofit 

должен это сделать

Вы можете реализовать тот же самый модуль

 @Module class ApiModule { @Provides @Singleton fun apiService(context: Context): WebService { val mBaseUrl = context.getString(if (BuildConfig.DEBUG) R.string.local_url else R.string.live_url) val loggingInterceptor = HttpLoggingInterceptor() loggingInterceptor.level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE val okHttpClient = OkHttpClient.Builder() .readTimeout(120, TimeUnit.SECONDS) .writeTimeout(120, TimeUnit.SECONDS) .connectTimeout(120, TimeUnit.SECONDS) .addInterceptor(loggingInterceptor) //.addNetworkInterceptor(networkInterceptor) .build() return Retrofit.Builder().baseUrl(mBaseUrl) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build().create(WebService::class.java) } } 

Также измените AppComponent

 @Singleton @Component(modules = arrayOf(ApplicationModule::class, ApiModule::class)) interface AppComponent { ... fun apiService(): WebService ... } 

ваши изменения

 @Component(modules = arrayOf(AndroidInjectionModule::class, AppModule::class, ApiModule ::class)) 

добавить APIModule в соответствующие вспомогательные модули также

ОБНОВИТЬ

 @Component(modules = arrayOf(AndroidInjectionModule::class, AppModule::class, ActivityBuilder::class)) @Singleton interface AppComponent { fun inject(app: PartnerApplication) fun apiService(): ApiHelper } 

и затем вводить, когда вы хотите использовать.

 @Inject var webService: WebService? = null 
Давайте будем гением компьютера.