作者:mobiledu2502887783 | 来源:互联网 | 2022-12-30 12:33
这是我的情况:
我希望所有活动都可以继承 BaseActivity
在中BaseActivity
,我要注入Navigator
(它有助于我管理Fragments
后退栈并在活动之间进行导航):
abstract class BaseActivity : DaggerAppCompatActivity() {
@Inject
lateinit var navigator: Navigator
@Inject
lateinit var prefs: SharedPreferences // injected via AppModule.kt, see below.
}
本Navigator
类需要FragmentManager
在其构造函数:
class Navigator @Inject constructor(
val fragmentManager: FragmentManager) {
// class body
}
我想从中提供FragmentManager
一个BaseActivity
对象BaseActivityModule
:
@Module
class BaseActivityModule {
@PerActivity
@Provides
fun provideFragmentManager(baseActivity: BaseActivity): FragmentManager {
return baseActivity.supportFragmentManager
}
}
这是我其余的组件和模块:
AppComponent.kt
@Singleton @Component(modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
ActivityBindingModule::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
fun inject(app: AndroidApplication)
}
AppModule.kt
@Module
class AppModule {
@Singleton
@Provides
fun providesPrefs(application: Application): SharedPreferences {
return application.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
}
}
ActivityBindingModule.kt
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
@ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
abstract fun bindBaseActivity(): BaseActivity
}
BaseActivityModule.kt
@Module
class BaseActivityModule {
@Provides
fun provideFragmentManager(baseActivity: BaseActivity): FragmentManager {
return baseActivity.supportFragmentManager
}
}
这是编译错误消息:
Error: [dagger.android.AndroidInjector.inject(T)]
android.support.v4.app.FragmentManager cannot be provided
without an @Provides- or @Produces-annotated method.
Error:A binding with matching key exists in component:
com.myapp.ActivityBindingModule_BindBaseActivity.BaseActivitySubcomponent
David Medenj..
7
问题在于您的假设,即您需要BaseActivity
在某个时候注入a 。
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
// ...that's not really how it works... :/
@ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
abstract fun bindBaseActivity(): BaseActivity
}
使用上面的代码,您最终要注入MainActivity
一些组件BaseActivity
,而要注入一些组件,但是都不能“注入”两者。您收到的错误是因为MainActivity
无法提供FragmentManager
它需要注入其父级中的错误BaseActivity
。它缺少这样做的模块。您只能将添加BaseActivityModule
到MainActivityComponent实际上无法访问的其他组件中,因此无法提供错误。
匕首始终需要注入整个对象。没有部分注入,也没有一次从多个组件注入。如果单个组件不能提供它需要的所有依赖关系,则会出现错误。您fun bindBaseActivity(): BaseActivity
是无用的,因为您将永远不会使用BaseActivity
,而只会使用MainActivity
它的或其他子类。这些组件还必须能够提供BaseActivity的依赖项。
如果要在BaseActivity中注入依赖项,则需要添加一个提供必要绑定的模块。您的代码最终应如下所示:
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector(modules = [BaseActivityModule::class, MainActivityModule::class])
abstract fun bindMainActivity(): MainActivity
// no BaseActivity component necessary
}
@Module
abstract class MainActivityModule {
@Binds
abstract fun bindBaseActivity(activity: MainActivity) : BaseActivity
}
这将执行以下操作:
它添加BaseActivityModule
到MainActivityComponent中,因此您的基本依赖关系可以由该组件提供并MainActivity
可以注入
它MainActivity
以您的身份绑定到另一个模块中,BaseActivity
因此您可以在模块中使用它,而不必为每个活动都绑定一个FragmentManager
尽管您可以重用BaseActivityModule
并将其添加到所有活动实现中,但是您将必须添加一个模块以将活动绑定BaseActivity
为每个活动中的一个。
可能有一种更优化的方法,但这就是注入子类的基本要求。
1> David Medenj..:
问题在于您的假设,即您需要BaseActivity
在某个时候注入a 。
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
// ...that's not really how it works... :/
@ContributesAndroidInjector(modules = [(BaseActivityModule::class)])
abstract fun bindBaseActivity(): BaseActivity
}
使用上面的代码,您最终要注入MainActivity
一些组件BaseActivity
,而要注入一些组件,但是都不能“注入”两者。您收到的错误是因为MainActivity
无法提供FragmentManager
它需要注入其父级中的错误BaseActivity
。它缺少这样做的模块。您只能将添加BaseActivityModule
到MainActivityComponent实际上无法访问的其他组件中,因此无法提供错误。
匕首始终需要注入整个对象。没有部分注入,也没有一次从多个组件注入。如果单个组件不能提供它需要的所有依赖关系,则会出现错误。您fun bindBaseActivity(): BaseActivity
是无用的,因为您将永远不会使用BaseActivity
,而只会使用MainActivity
它的或其他子类。这些组件还必须能够提供BaseActivity的依赖项。
如果要在BaseActivity中注入依赖项,则需要添加一个提供必要绑定的模块。您的代码最终应如下所示:
@Module
abstract class ActivityBindingModule {
@ContributesAndroidInjector(modules = [BaseActivityModule::class, MainActivityModule::class])
abstract fun bindMainActivity(): MainActivity
// no BaseActivity component necessary
}
@Module
abstract class MainActivityModule {
@Binds
abstract fun bindBaseActivity(activity: MainActivity) : BaseActivity
}
这将执行以下操作:
它添加BaseActivityModule
到MainActivityComponent中,因此您的基本依赖关系可以由该组件提供并MainActivity
可以注入
它MainActivity
以您的身份绑定到另一个模块中,BaseActivity
因此您可以在模块中使用它,而不必为每个活动都绑定一个FragmentManager
尽管您可以重用BaseActivityModule
并将其添加到所有活动实现中,但是您将必须添加一个模块以将活动绑定BaseActivity
为每个活动中的一个。
可能有一种更优化的方法,但这就是注入子类的基本要求。