我目前大致熟悉dagger2和依赖项注入。我认为我对基础知识有一定的了解,但是在理解范围方面遇到了麻烦。我有两件事希望对您有所帮助。 A)关于范围生存期,B)关于范围的多次重用。
当谈到作用域时,总是会出现作用域生存期的想法。我收集到,对于在给定作用域下提供的依赖项,将在该作用域为“活动”时提供一个实例。究竟是什么决定示波器是活着还是死了?它与带有注释的组件的寿命相关联吗?如果该组件超出范围并且是GC,那该范围的死亡了吗?
也是一个相关的问题:说我有一些依赖关系,我想将其范围限定为两个活动之一。我是否需要创建两个单独的作用域(即@MainActivityScope
和@SettingsActivityScope
),还是可以使用同时用于两者的通用活动范围(@ActivityScope
),但根据其使用方式来表示两个单独的作用域?也许当我理解我的第一个问题时,这将有助于我理解该问题的答案。
谢谢。
最佳答案
Dagger以最简单的方式处理范围:范围属于Component实例。如果您有作用域绑定,它将被存储在具有匹配作用域的Component实例中并从中检索。
@Singleton @Component(...) public interface MyComponent {
ActivityComponent createActivityComponent(); // creates a new ActivityComponent
Thing1 getThing1(); // @Singleton
Thing2 getThing2(); // no scope
}
@ActivityScope @Subcomponent(...) public interface ActivityComponent {
Thing3 getThing3(); // @ActivityScoped
Thing4 getThing4(); // no scope
}
“生死攸关”的概念在这里并不重要。重要的是,通过创建的每个ActivityComponent,您将获得Thing3的不同实例,但获得Thing1的相同实例。如果为您创建的每个活动创建一个新的ActivityComponent实例,则当该活动被销毁时,该组件将(理想情况下)变得不可访问并被收集。但是,就Dagger而言,您可以创建任意数量的ActivityComponents并将它们共存。
MyComponent myComponent = DaggerMyComponent.create();
Thing1 a = myComponent.getThing1();
Thing1 b = myComponent.getThing1(); // b == a
Thing2 c = myComponent.getThing2();
Thing2 d = myComponent.getThing2(); // c != d
未作用域意味着每次注入都有新实例。现在让我们尝试子组件:
ActivityComponent activityComponent1 = myComponent.createActivityComponent();
Thing3 e = activityComponent1.getThing3();
Thing3 f = activityComponent1.getThing3(); // e == f
ActivityComponent activityComponent2 = myComponent.createActivityComponent();
Thing3 g = activityComponent2.getThing3(); // e != g
// But you can still use activityComponent1. It's not dead.
Thing3 h = activityComponent1.getThing3(); // e == h
自然,这也会在图中传播:如果Thing2依赖于Thing1,则可能有许多Thing2实例,每个实例都依赖于一个公共的单例Thing1实例。如果Thing4依赖于Thing1,Thing2和Thing3,则您可能有许多Thing4实例,每个实例都有自己的Thing2,并且Thing3在同一活动(组件)中共享,Thing1在同一总体(应用程序/单个)组件中共享。
只要它们都是单独的层次结构的一部分,就可以根据需要具有任意多个ActivityComponent或@ActivityScoped组件。您可以选择制作一个@ActivityScoped MainActivityComponent和一个@ActivityScoped SettingsActivityComponent,或者制作一个知道如何注入它们的单个公共ActivityComponent。您可能不需要@MainActivityScope和@SettingsActivityScope,因为一个永远不会从另一个派生。重要的是,您需要为每个活动实例创建一个新的@ActivityScoped组件实例,这是Dagger保持范围一致所需要的。