android - Dagger 2 错误:依赖“不能在没有 @Provides 注释的方法的情况下提供”
问题描述
我已经开始使用带有 Android Injector 的 Dagger 2 并遇到了一个问题
我有 5 个模块,它们组成一个组件
@Singleton
@Component(modules = [AndroidInjectionModule::class,
ActivityBuilder::class,
AndroidSupportInjectionModule::class
, ApplicationModule::class,NetworkModule::class])
interface ApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ApplicationComponent
}
fun inject(app: DeliveryApplication)
fun service(): DeliveryApi
}
网络模块看起来像
@Module
class NetworkModule {
@Singleton
@Provides
fun providesDeliveryApi(retrofit: Retrofit):DeliveryApi = retrofit.create(DeliveryApi::class.java)
@Singleton
@Provides
fun providesRetrofit(okHttpClient: OkHttpClient):Retrofit =
Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
@Singleton
@Provides
fun providesOkHttpClient(context:Context): OkHttpClient {
/* val logging = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}*/
val cacheSize = (5 * 1024 * 1024).toLong()
val myCache = Cache(context.cacheDir, cacheSize)
val okHttpClient = OkHttpClient.Builder()
.cache(myCache)
.addInterceptor { chain ->
var request = chain.request()
request = if (hasNetwork(context)!!)
// setting 5 Mb Cabacity
request.newBuilder().header("Cache-Control", "public, max-age=" + 5).build()
else
request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 7).build()
chain.proceed(request)
}
.build()
return okHttpClient
}
@Singleton
@Provides
fun provideImageLoader(context: Context) : ImageLoader {
return PicassoImageLoader(Picasso.with(context))
}
应用模块看起来像
const val SCHEDULER_MAIN_THREAD = "mainThread"
const val SCHEDULER_IO = "io"
@Module
class ApplicationModule {
@Provides
@Named(SCHEDULER_MAIN_THREAD)
fun provideAndroidMainThreadScheduler() : Scheduler = AndroidSchedulers.mainThread()
@Provides
@Named(SCHEDULER_IO)
fun provideIoScheduler() : Scheduler = Schedulers.io()
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application
}
}
ActivityBuilder 非常简单:只是将活动模块和片段模块组合在一起
@Module
abstract class ActivityBuilder {
@PerActivity
@ContributesAndroidInjector(modules = [FragmentsModule::class, DeliveriesModule::class])
abstract fun bindMainActivity(): DeliveriesActivity
@PerActivity
@ContributesAndroidInjector(modules = [FragmentsModule::class, DeliveriesDetailsModule::class])
abstract fun bindDeliveryDetailsActivity(): DeliveryDetailsActivity
}
@Module
abstract class FragmentsModule {
@ContributesAndroidInjector
abstract fun provideDeliveriesListFragment(): DeliveriesListFragment
@ContributesAndroidInjector
abstract fun provideDeliveryDetailsFragment(): DeliveryDetailsFragment
}
Delivery Module,用于提供 DeliveryActivity 的所有实例
@Module
class DeliveriesModule {
@Provides
@PerActivity
fun providesDeliveryRepository(deliveryApi: DeliveryApi): DeliveryRepository {
return DeliveryDownloader(deliveryApi)
}
@Provides
@PerActivity
fun providesDeliveryListUseCases(deliveryRepository: DeliveryRepository): DeliveryListUseCase {
return DeliveryListInteractor(deliveryRepository)
}
@Provides
@PerActivity
fun provideDeliveriesListFragment(): DeliveriesListFragment {
return DeliveriesListFragment()
}
}
ViewModelFactory 哪里有问题,编译器说没有@Provides-annotated 方法就不能提供DeliveryListUseCase
class ViewModelFactory @Inject constructor(private val application: Application,
@Named(SCHEDULER_IO) val subscribeOnScheduler: Scheduler,
@Named(SCHEDULER_MAIN_THREAD) val observeOnScheduler: Scheduler,
private val deliveryListUseCase: DeliveryListUseCase) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return when {
modelClass.isAssignableFrom(DeliveryListViewModel::class.java) ->
DeliveryListViewModel(application,deliveryListUseCase,subscribeOnScheduler,observeOnScheduler) as T
else -> BaseViewModel(application) as T
}
}
}
解决方案
好像我已经弄清楚出了什么问题
问题。DeliveriesModule 是 DeliveriesActivity 的一个模块,所以我必须为 DeliveriesListFragment 制作另一个模块并提供 DeliveryListUseCase
谢谢@Blackbelt,给我一个提示
推荐阅读
- cron - 每月第二个星期日触发的 Azure 函数 Cron 表达式是什么?
- reactjs - AntD React:在 DateRangePicker 中禁用特定日期的时间范围
- django - 如何在 Django 中嵌套验证错误
- java - 如何覆盖 RequestParam 的默认行为?
- powershell - Powershell 在 MDT 任务序列中返回退出代码 0 或 1
- php - 基于变量的页面模板内的Wordpress重定向
- r - 如何使用“readxl”包从 .xlsx 文件中选择两个特定列?
- docker - oc/kubectl 补丁替换整行
- ffmpeg - 在 Mac 和 Linux 上工作时,在 Windows 上进行连接会引发“处理输入时发现无效数据”
- php - 我无法从 codeigniter 3.1.11 中的 URl 中删除 index.php