将匕首子组件注入活动的问题

时间:2018-12-13 12:55:19

标签: android dagger-2 dagger

我很难弄清楚如何设置Dagger组件层次结构以符合我的愿景。任何帮助将不胜感激,如果发现任何漏洞,请随时批评它。

我们要点了。

我正在尝试兑现与用户注册有关的部分应用程序。由于注册是一个自包含域,因此我认为它是单独的匕首组件(RegistrationSubcomponent)的不错的选择。在该注册域中,我将显示一个活动(RegistrationActivity),并在其顶部显示一些片段(RegistrationFragment1,RegistrationFragment2等)。我已经有一个应用程序组件(AppComponent),其应用程序的生命周期应为RegistrationSubcomponent的父级。 AppComponent用于将依赖项注入到除RegistrationActivity之外的其他活动中,也注入到一个公共活动(CommonActivity)中,该活动是我的应用程序中每个活动(包括RegistrationActivity)的父级。要将依赖项注入RegistrationActivity,我想使用RegistrationSubcomponent。

应该在显示RegistrationActivity之前立即实例化RegistrationSub组件,并且应该一直存在,直到RegistrationActivity返回。我不想将RegistrationSubcomponent生命周期与RegistrationActivity生命周期绑定。也许在这种情况下可能是有道理的,但将来我可能想为其他应用程序域创建可能不一定与它们包含的活动的生命周期相匹配的组件。

通常,问题是将RegistrationComponent中指定的依赖项注入RegistrationActivity以及RegistrationFragments中。

问题是,导航到RegistrationActivity时,应用崩溃,并显示以下错误: 无法启动活动ComponentInfo {pl.kermit.diproblem / pl.kermit.diproblem.activities.RegistrationActivity}:java.lang.IllegalArgumentException:没有为类绑定喷油器工厂

存在问题的最小项目可以在https://github.com/mariola3000/DIProblemStack01

找到

下面我将代码中最重要的部分放在

// APP组件

@Singleton
@Component(modules = [AndroidInjectionModule::class, AppModule::class, AppAndroidBindingModule::class,
    AndroidSupportInjectionModule::class])
interface AppComponent {
    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }

    fun inject(application: Application)
}

@Module(subcomponents = [RegistrationComponent::class])
class AppModule {
    @Provides
    fun provideGlobalDependency(): GlobalDependency {
        return GlobalDependency("GlobalDependency")
    }
    @Provides
    fun provideGlobal2Dependency(): Global2Dependency {
        return Global2Dependency("Global2Dependency")
    }
}

@Module
abstract class AppAndroidBindingModule {

    @PerActivity
    @ContributesAndroidInjector()
    abstract fun bindMainActivity(): MainActivity

}

//注册组件

@PerRegistration
@Subcomponent(modules = [RegistrationModule::class, RegistrationAndroidBindingModule::class])
interface RegistrationComponent {
    @Subcomponent.Builder
    interface Builder {
        fun requestModule(module: RegistrationModule): Builder
        fun build(): RegistrationComponent
    }
}

@Module
class RegistrationModule {
    @PerRegistration
    @Provides
    fun provideRegistrationDependency(): RegistrationDependency {
        return RegistrationDependency("RegistrationDependency")
    }

    @PerRegistration
    @Provides
    fun provideRegistrationFragmentDependency(): RegistrationFragmentDependency {
        return RegistrationFragmentDependency("RegistrationFragmentDependency")
    }
}

@Module
abstract class RegistrationAndroidBindingModule {
    @PerActivity
    @ContributesAndroidInjector
    abstract fun bindRegistrationActivity(): RegistrationActivity

    @PerFragment
    @ContributesAndroidInjector
    abstract fun bindRegistrationFragment(): RegistrationFragment
}

//活动

abstract class CommonActivity : DaggerAppCompatActivity(){
    @Inject
    lateinit var globalDependency: GlobalDependency

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)

        Toast.makeText(this, "global message: " + globalDependency.message, Toast.LENGTH_LONG).show()
    }
}

class MainActivity : CommonActivity() {
    @set:Inject
    lateinit var global2Dependency: Global2Dependency

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text: TextView = findViewById(R.id.main_text)

        text.text = global2Dependency.message

        val button: Button = findViewById(R.id.main_button)
        button.setOnClickListener {
            startActivity(Intent(this, RegistrationActivity::class.java))
        }
    }
}

class RegistrationActivity : CommonActivity() {
    @Inject
    lateinit var registrationDependency: RegistrationDependency

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_registration)

        val registrationMessage = findViewById<TextView>(R.id.registration_text)
        registrationMessage.text = registrationDependency.message

        val transaction = this.supportFragmentManager.beginTransaction()
        val fragment = RegistrationFragment()
        transaction.replace(R.id.registration_fragment_container, fragment)
        transaction.addToBackStack(fragment.javaClass.simpleName)
        transaction.commit()
    }
}

0 个答案:

没有答案