在不同的活动中使用 AppComponent.Inject() (Dagger2)

我有两个使用 ViewModelProvider 的活动,必须注入 Dagger。

要在活动中提供注入,我必须调用 appComponent.inject() 方法。我可以进入 Mainactivity。但是我不能在其他活动中使用它(显然是因为 appComponent.inject() 将 Mainactivity 实例作为参数)。

所以,问题是: 我应该如何处理 AppComponent(或其他),以便能够从不同的活动(不仅是从 Mainactivity)获取 AppComponent 的实例。

附言可能是关于 Dagger Scopes,但我不知道具体要做什么。

AppComponent.kt

...
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {

    fun inject(mainactivity: Mainactivity) 

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun create(): AppComponent
    }
}

Mainactivity.kt

class Mainactivity : AppCompatactivity() {

    @Inject
    lateinit var viewModelProvider: Provider<MainactivityViewModel.Factory>

    private val viewModel: MainactivityViewModel by viewModels { viewModelProvider.get() }

    private lateinit var recyclerView : RecyclerView

    private val adapter by lazy(LazyThreadSafetyMode.NONE) {
        RecyclerViewAdapter(this) 
}

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

        setContentView(R.layout.activity_main)

        setupViewModel()
        setupUI()
    }

    private fun setupViewModel(){
        viewModelProvider.get()
        viewModel.setQuery("Apple")
    }

    private fun setupUI(){
        recyclerView = findViewById(R.id.recyclerView)

        GridLayoutManager(this,3,RecyclerView.VERTICAL,false
        ).apply {
            recyclerView.layoutManager = this
        }

        recyclerView.adapter = adapter
        addRepeatingJob(Lifecycle.State.STARTED) {
            viewModel.images.collectLatest(adapter::submitData)
        }
    }
}

ViewPager.kt


class ViewPageractivity : AppCompatactivity() {

    @Inject
    lateinit var viewModelProvider: Provider<MainactivityViewModel.Factory>
    private val viewModel: MainactivityViewModel by viewModels { viewModelProvider.get() }

    private lateinit var viewPager: ViewPager2

    private val adapter by lazy(LazyThreadSafetyMode.NONE) {
        ViewPagerAdapter(this) 
    }

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

        setContentView(R.layout.activity_view_pager)
        Log.d("dbg",intent.getIntExtra("ARG",0).toString())

        setupViewModel() 
        setupUI();
    }

    private fun setupUI()
    {
        viewPager = findViewById(R.id.viewPager)

        viewPager.adapter = adapter
        addRepeatingJob(Lifecycle.State.STARTED) {
            viewModel.images.collectLatest(adapter::submitData)
        }

    }

    private fun setupViewModel()
    {
        viewModelProvider.get()
    }

}

谢谢。

cuijuncyanway 回答:在不同的活动中使用 AppComponent.Inject() (Dagger2)

AppComponent 的构建器接受一个应用程序。您尚未指定如何创建或存储 AppComponent,但大概是在 Application 实例中或在静态字段中以保留其 @Singleton 属性。

在这种情况下,您可以创建第二个 inject 方法,名称类似或不同,它采用您的 SecondActivity

    fun inject(mainActivity: MainActivity)

    fun inject(secondActivity: SecondActivity) 

每个都是一个成员注入方法:Dagger 将在编译时检查对象,找出标有 @Inject 注释的内容,并调用方法并填充字段当您拨打 inject 时。您可以为此使用相同的组件或使用不同的组件。

最终,如果您希望能够在一个 Activity 中注入相同的实例,但在不同的 Activity 之间注入不同的实例,您可以查看第二个组件(可能是一个子组件),其范围注释类似于 @ActivityScope会写。您还可以考虑采用 Hilt,它会为您管理其中一些范围。

本文链接:https://www.f2er.com/1643.html

大家都在问