Dagger2可以提供活动依赖于匕首
没有@Inject构造函数或 @提供通知的方法。这种类型支持会员注射,但 不能隐式提供。
我正在使用匕首android,我通过androidivect.iment(this)注入了主动,但在模块中仍然无法使用。我准备了示例项目: https://github.com/github.com/deepsorory/testsororcor/test_daggersusissu.git.git.git.git 下面列出:
FactoryVmmodule:
@Module
class FactoryVmModule {
@Provides
@Named("TestVM")
fun provideTestVM(
activity: MainActivity, // <--- dagger can't inject this
viewModelFactory: ViewModelFactory
): TestVM =
ViewModelProvider(activity, viewModelFactory)[TestVM::class.java]
}
MainActivityModule:
@Module
abstract class MainActivityModule {
@ContributesAndroidInjector
abstract fun injectMainActivity(): MainActivity
}
MainActivity(使用DaggerAppCompatactivity):
class MainActivity : DaggerAppCompatActivity() {
@Named("TestVM")
@Inject
lateinit var testVM: TestVM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
TestApplication:
class TestApplication : Application(), HasAndroidInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
override fun onCreate() {
super.onCreate()
DaggerAppComponent.create().inject(this)
}
override fun androidInjector() = dispatchingAndroidInjector
}
AppComponent:
@Component(modules = [AndroidInjectionModule::class, MainActivityModule::class, ViewModelModule::class, FactoryVmModule::class])
interface AppComponent {
fun inject(application: TestApplication)
}
MainActivity cannot be provided without an @Inject constructor or an
@Provides-annotated method. This type supports members injection but
cannot be implicitly provided.
I'm using dagger-android, I injected MainActivity through AndroidInjection.inject(this), but it's still unavailable in Module. I prepared sample project: https://github.com/deepsorrow/test_daggerIssu.git, files listed below:
FactoryVmModule:
@Module
class FactoryVmModule {
@Provides
@Named("TestVM")
fun provideTestVM(
activity: MainActivity, // <--- dagger can't inject this
viewModelFactory: ViewModelFactory
): TestVM =
ViewModelProvider(activity, viewModelFactory)[TestVM::class.java]
}
MainActivityModule:
@Module
abstract class MainActivityModule {
@ContributesAndroidInjector
abstract fun injectMainActivity(): MainActivity
}
MainActivity (using DaggerAppCompatActivity):
class MainActivity : DaggerAppCompatActivity() {
@Named("TestVM")
@Inject
lateinit var testVM: TestVM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
TestApplication:
class TestApplication : Application(), HasAndroidInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
override fun onCreate() {
super.onCreate()
DaggerAppComponent.create().inject(this)
}
override fun androidInjector() = dispatchingAndroidInjector
}
AppComponent:
@Component(modules = [AndroidInjectionModule::class, MainActivityModule::class, ViewModelModule::class, FactoryVmModule::class])
interface AppComponent {
fun inject(application: TestApplication)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
dagger.android /dagger.dev/dev-guide/android.html#injecting-activity-objects“ rel =” nofollow noreferrer“> explicit版本
@contributesandroidInjector
为您生成,其中生成androidInjector.factory.factory
@bindsinstance
binding 您在此处请求的类型。这对您不起作用,因为您正在将MainActivity注入安装在顶级组件上的绑定中。这是一个问题,因为AppComponent将在活动之前存在,并且还将替换为Android重新创建活动:通过
@component.builder
是 not 围绕这个问题。相反,将
factoryvmmodule :: class
移动到子组件中,@contributesandroidInjector
生成,您可以通过将其包括在我也将您的ViewModelModule类移动到其中;尽管如果不取决于活动的任何内容,您可能会将其放在顶级组件中,但您可能需要将它们保持在一起。子组件中的绑定从应用程序继承,因此您可以从活动的子组件中注入AppComponent级的绑定,但相反的绑定。这意味着您将无法在活动之外注入VM实例(这里,TestVM),但是如果它们依赖于活动,您都不会想:这些实例可能会陈旧,并防止垃圾收集者收回您的收回完成的活动实例。
dagger.android does do this automatically: See the explicit version of the binding that
@ContributesAndroidInjector
generates for you, where the generatedAndroidInjector.Factory
contains a@BindsInstance
binding of the type you request here.This isn't working for you because you are injecting MainActivity in a binding that is installed on your top-level component. This is a problem because AppComponent will exist before the Activity does, and will also be replaced as Android recreates the Activity: Passing an instance through
@Component.Builder
is not a way around this problem.Instead, move your
FactoryVmModule::class
to within the subcomponent that@ContributesAndroidInjector
generates, which you can do by including it in themodules
attribute on@ContributesAndroidInjector
. Dagger will create a different subcomponent instance per Activity instance, so your FactoryVmModule will always have a fresh binding to MainActivity.I moved your ViewModelModule class there as well; though it's possible you could leave it in your top-level Component if it doesn't depend on anything belonging to the Activity, you might want to keep them together. Bindings in subcomponents inherit from the application, so you can inject AppComponent-level bindings from within your Activity's subcomponent, but not the other way around. This means you won't be able to inject VM instances (here, TestVM) outside your Activity, but if they depend on the Activity, you wouldn't want to anyway: Those instances might go stale and keep the garbage collector from reclaiming your finished Activity instances.