为什么我必须用它将要使用的范围注释Dagger组件?为什么注释类本身还不够?
答案 0 :(得分:3)
因为范围本身并不意味着任何东西。是组件及其关系将意义引入了范围。
可以使用任何组件提供不受作用域的对象,只要它们的依赖关系可用。由于它们没有作用域,所以每次调用它们的提供程序时都会创建一个新对象。有作用域的对象将共享相同作用域的组件的生命周期,并且只能每个组件一次创建。如果重新创建组件,则将重新创建其范围内的所有对象。这将使事情变得棘手。
假设您具有以下设置:一个组件和一个子组件,通常是这样。
@Component interface MyComponent {}
@Subcomponent interface MySubComponent {}
现在,我们有两个类,Foo
中的@FooScope
和Bar
中的@BarScope
。两者都支持构造函数注入,并且都在各自的类上具有范围注释。假设我们在子组件中添加了这两种方法的提供方法:
@Subcomponent
interface MySubComponent {
Foo getFoo();
Bar getBar();
}
现在有个大问题: Foo
或Bar
在哪里创建,它们共享哪个组件的“生命周期”?
我们确实知道Foo
和Bar
在不同的范围内,仅此而已。如果一个依赖另一个,我们可以 推断一个驻留在(父)组件中,另一个驻留在子组件中,因为一个人只能依赖相同或更高范围的对象,但这仅适用于这种简单的设置,并且如果我们决定向该设置中添加第三个组件,则会再次使我们不确定。
如果我们有3个范围,但只有两个组成部分,会发生什么?这两个组件中的哪个组件应具有两个作用域(如果这还有意义)?或者,如果要报告错误,哪个范围是“错误的范围”?根本无法确定。
如果您还向该组件添加了范围,则这些问题将消失。现在将很清楚,哪个组件处理哪个(范围内的)对象,并且在引入未知范围的情况下很容易报告错误。
答案 1 :(得分:0)
我们需要本地化,因为我们不希望所有依赖项都与应用程序一样长寿,并且在某些情况下,我们希望我们的依赖项不因成为同一对象而共享相同的状态。 活动具有自己的Presenter或ViewModel,1个或多个Presenters或ViewModel可能需要一个交互器,并且交互器取决于数据层。 Dagger 2提供@Scope作为处理范围的机制。范围界定允许您保留对象实例,并在范围化组件的持续时间内将其作为本地单例提供。 范围关心的是保持类的单个实例,只要它的范围存在。实际上,这意味着@ApplicationScope中作用域的实例与Application对象一样长。只要Activity存在,@ ActivityScope就会保留引用(例如,我们可以在此Activity托管的所有片段之间共享任何类的单个实例)。 简而言之,作用域为我们提供了“局部单例”,它们与作用域本身一样长寿。