在这里,依赖的匕首组件会抛出一个错误android.content.Context,如果没有@Provides注释的方法就无法提供。
这是我的 CoreDataComponent ,它为coreDataModule和contextModule生成代码
@Singleton
@Component( modules = [
CoreDataModule::class,
ContextModule::class
]
)
interface CoreDataComponent{
@Component.Builder interface Builder {
fun build(): CoreDataComponent
fun coreDataModule(coreDataModule: CoreDataModule) : Builder
fun contextModule(contextModule: ContextModule) : Builder
}
}
CoreDataModule
@Module
class CoreDataModule {
@Provides
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().apply {
level = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
}
}
@Provides
fun provideOkHttpClient(context: Context): OkHttpClient =
OkHttpClient.Builder()
.addInterceptor(provideLoggingInterceptor())
.addInterceptor(ChuckInterceptor(context))
.addInterceptor { chain ->
val url = chain.request().url().newBuilder().addQueryParameter("access_token", "").build()
val request = chain.request().newBuilder().url(url).build()
chain.proceed(request)
}
.cache(null)
.build()
@Provides
fun provideRetrofit(
okHttpClient: OkHttpClient
): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.BASE_DOMAIN)
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(okHttpClient)
.build()
}
}
ContextModule
@Module
class ContextModule(val context: Context) {
@Provides
fun provideApplicationContext(): Context {
return context
}
}
这是我的依赖组件
@Component(
modules = [
AuthDataModule::class,
AuthViewModelModule::class
],
dependencies = [
CoreDataComponent::class
]
)
@ActivityScope
interface AuthDataComponent {
@Component.Builder interface Builder {
fun build() : AuthDataComponent
fun coreDataComponent(coreDataComponent: CoreDataComponent) : Builder
/*@BindsInstance
fun activityContext(context: Context) : Builder*/
}
fun inject(authenticationActivity: AuthenticationActivity)
fun inject(loginFragment: LoginFragment)
....
}
这是我如何构建CoreDataComponent和AuthDataComponent
class Application : Application() {
private val coreDataComponent: CoreDataComponent by lazy {
DaggerCoreDataComponent
.builder()
.coreDataModule(CoreDataModule())
.contextModule(ContextModule(this))
.build()
}
companion object {
@JvmStatic
fun coreDataComponent(context: Context) =
(context.applicationContext as Application).coreDataComponent
}
}
/// Injection
fun AuthenticationActivity.inject() {
DaggerAuthDataComponent.builder()
.coreDataComponent(Application.coreDataComponent(this))
//.activityContext(this)
.build()
.inject(this)
错误日志
error: android.content.Context cannot be provided without an @Provides-annotated method.
public abstract void inject(@org.jetbrains.annotations.NotNull()
android.content.Context is injected at
com.stylabs.collabb.core.dagger.module.CoreDataModule.provideOkHttpClient(context)
我不明白,父组件已经提供了上下文。
更新1 仅当我将AuthDataComponent依赖项注入Fragment而不在Activity中抛出错误时才会发生这种情况
更新2 这是完整的错误跟踪
public abstract void inject(@org.jetbrains.annotations.NotNull()
^
android.content.Context is injected at
com.stylabs.collabb.core.dagger.module.CoreDataModule.provideOkHttpClient(context)
okhttp3.OkHttpClient is injected at
com.stylabs.collabb.core.dagger.module.CoreDataModule.provideRetrofit(okHttpClient)
retrofit2.Retrofit is injected at
com.stylabs.collabb.features.auth.data.dagger.module.AuthDataModule.providesAuthApi(retrofit)
com.stylabs.collabb.features.auth.data.source.AuthApi is injected at
com.stylabs.collabb.features.auth.data.dagger.module.AuthDataModule.providesAuthRemoteDataSource(authApi)
com.stylabs.collabb.features.auth.data.source.AuthRemoteDataSource is injected at
com.stylabs.collabb.features.auth.data.dagger.module.AuthDataModule.providesAuthRepository(authRemoteDataSource)
com.stylabs.collabb.features.auth.data.source.AuthRepository is injected at
com.stylabs.collabb.features.auth.data.AuthViewModel.<init>(authRepository)
com.stylabs.collabb.features.auth.data.AuthViewModel is injected at
com.stylabs.collabb.features.auth.login.ui.LoginFragment.authViewModel
com.stylabs.collabb.features.auth.login.ui.LoginFragment is injected at
com.stylabs.collabb.features.auth.data.dagger.component.AuthDataComponent.inject(loginFragment)