代码之家  ›  专栏  ›  技术社区  ›  Trace

Dagger2范围,每个组件的实例

  •  0
  • Trace  · 技术社区  · 5 年前

    在网上的许多资源中,你会发现 @ActivityScope @FragmentScope 添加到为活动和片段提供绑定的组件中。

    我想确认一下,这意味着所有活动/所有片段将分别有一个实例。


    你能证实这个假设是正确的吗?

    编辑:

    关于存储作用域对象的位置(两个子组件 范围注释。)

    这似乎假设如果有多个组件使用相同的注释,那么当相同的注释 scope

    scope instance 指。这实际上是指绑定?
    这是否只适用于子组件?

    0 回复  |  直到 5 年前
        1
  •  2
  •   David Medenjak    5 年前

    作用域组件将在第一次使用它时创建一个作用域对象,然后它将保留它。如果第二次创建同一个组件,它也会在第一次使用时创建作用域对象。组件只是对象,它们不保持任何全局(静态)状态,因此如果您重新创建组件,您将重新创建所有组件。

    val component = DaggerScopedComponent.create()
    component.getScopedObject() === component.getScopedObject() // always the same object!
    
    // never the same object! two different components, albeit same scope
    DaggerScopedComponent.create().getScopedObject() != DaggerScopedComponent.create().getScopedObject() 
    

    匕首生成代码,所以我邀请你创建一个 简单的 示例并查看代码。e、 上面的样本应该很容易阅读

    @Singleton class Foo @Inject constructor()
    
    @Singleton @Component interface ScopedComponent {
      fun getScopedObject() : Foo
    }
    

    假设我们在上面的例子中添加了一个子组件

    @Singleton class Foo @Inject constructor()
    
    @Singleton @Component interface ScopedComponent {
        fun getScopedObject() : Foo
    
        fun subComponent() : SubComponent
    }
    
    
    @Other @Subcomponent interface SubComponent {
        fun getScopedObject() : Foo
    }
    
    @Scope
    @MustBeDocumented
    annotation class Other
    

    只要我们使用相同的 @Singleton 我们总是得到相同的成分 作用域对象。

    // Subcomponents will have the same object as the parent component
    component.subComponent().getScopedObject() === component.getScopedObject()
    
    // as well as different Subcomponents
    component.subComponent().getScopedObject() === component.subComponent().getScopedObject()
    

    现在回答你的问题。。。


    我想确认一下,这意味着所有活动/所有片段将分别有一个实例。 也就是说,如果两个活动使用同一个组件来接收来自用范围“Activity”注释的同一组件的依赖项,那么两个活动将接收相同的实例(就像singleton注释一样)。

    @ActivityScope MyActivityComponent 然后一切都在范围之内 @ActivityScoped 将创建 每个组件一次 .

    如果要在活动的组件之间共享对象,必须使用 范围并保留对已创建组件的引用。


    所以在这种情况下,使用@ActivityScope和@FragmentScope注释只会有助于区分活动和片段之间的依赖生存期。

    不,因为你可以有一个 @ActivityScope FooActivityComponent 和一个 ActivityScope BarActivityComponent 他们会的 从未 分享 @ActivityScope class FooBar @ActivityScope 作用域组件。

    @ActivityScope LoginActivityComponent @活动范围 作用域对象。您可以在这里使用相同的范围。如果您愿意,也可以创建一个不同的范围,但在这里没有区别。


    我发现范围实例所指的内容有点不清楚。这实际上是指绑定?这是否只适用于子组件?

    你不能有像这样的组件层次结构 Singleton > ActivityScope > ActivityScope 因为那些重复的作用域将使我们无法知道 @活动范围 作用域对象是第一个或第二个对象的一部分。

    您可以拥有同一范围内的两个不同组件、同一父级的两个子组件(它们不能“接触”彼此)和任何子组件 作用域对象将是后者的一部分 @活动范围

    • Singleton > ActivityScope FooComponent
    • Singleton > ActivityScope BarComponent

    我建议你暂时忘掉Android,只需使用Dagger和生成的代码,就像上面显示的代码一样。一旦“魔力”消失了,你会发现它只是一个POJO,里面有一些变量,这是最快的方法来弄清楚事情是如何运作的。