gpt4 book ai didi

android - Dagger2 单例实际上不是单例问题

转载 作者:行者123 更新时间:2023-11-29 01:04:34 26 4
gpt4 key购买 nike

我有一个对象,我试图使用 @Inject 注释将其作为单例注入(inject)到 3 个 fragment 中。

组件:

@Subcomponent(modules = [(MyModule::class)])
interface MyComponent {

fun inject(fragment: OneFragment)
fun inject(fragment: TwoFragment)
fun inject(fragment: ThreeFragment)

}

模块:

@Module
class MyModule(val view: MyView) {

@Provides
fun provideView(): MyView = view

@Provides
fun providePresenter(view: MyView,
myService: MyService): MyPresenter =
MyPresenterImpl(view, myService)

}

MyPresenterImpl:

@Singleton
class MyPresenterImpl(override val view: MyView,
override val myService: MyService): MyPresenter {

private val TAG = javaClass.simpleName

// other code (irrelevant)
}

fragment :

class OneFragment : Fragment() {

@Inject
lateinit var myPresenter: MyPresenter

override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?,
bundle: Bundle?): View? {
activity?.mainApplication?.appComponent?.plus(
MyModule(activity as MyActivity))?.inject(this)

val view = inflater.inflate(R.layout.fragment_one, viewGroup, false)

//other meaningless code

return view
}
}

但是,注入(inject)到 fragment 中的演示者不是同一个唯一实例。我做错了什么?

最佳答案

它不是 @Singleton 因为你没有告诉 Dagger 它是。您将范围放在演示者上,如果您使用构造函数注入(inject),这会很好,但您没有。

@Singleton // does nothing. you're not doing constructor injection.
class MyPresenterImpl(override val view: MyView,
override val myService: MyService): MyPresenter


// ...and in your module...


@Provides // where's the scope? it's unscoped.
fun providePresenter(view: MyView,
myService: MyService): MyPresenter =
MyPresenterImpl(view, myService)

所以你有两个选择。要么使用构造函数注入(inject),要么使用 @Provides。您不能挑选并使用每一种。

1。构造函数注入(inject)

只需删除模块中的 @Provides 注释方法,然后在构造函数上添加一个 @Inject

@Singleton // NOW we're doing constructor injection -> singleton!
class MyPresenterImpl @Inject constructor(override val view: MyView,
override val myService: MyService): MyPresenter

现在不需要模块声明它。如果你想将它绑定(bind)到一个接口(interface),你可以使用 @Binds 注释并继续使用构造函数注入(inject)...

@Binds // bind implementation to interface
abstract fun providePresenter(presenter : MyPresenterImpl) : MyPresenter

由于MyPresenterImpl 是一个@Singleton,您不必也将MyPresenter 声明为单例。它将始终使用引擎盖下的单例。 (我相信它甚至可能会对两者都进行范围的性能损失略大。)

2。 @Provides 方法

从您的类中删除作用域(它除了混淆之外什么都不做),并将其放在 @Provides 方法上。就是这样。

@Singleton // singleton!
@Provides
fun providePresenter(view: MyView,
myService: MyService): MyPresenter =
MyPresenterImpl(view, myService)

用于构造函数注入(inject)的类的作用域,或者 @Provides 方法的作用域(如果您正在使用它)。不要混淆它们。

我个人建议尽可能进行构造函数注入(inject),因为您不必自己管理/更新构造函数调用。

关于android - Dagger2 单例实际上不是单例问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48270000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com