我目前正在熟悉dagger2和依赖注入。我认为我对基础知识有一定的把握,但我无法理解范围。有两件事我想帮助理解。 A)关于范围生存期,B)关于范围重复使用多次。
当谈到范围时,范围的生命周期的想法总是会出现。我认为,对于在给定范围内提供的依赖关系,将提供单个实例,而该范围是“活着的”。究竟是什么决定了一个范围是活着还是死了?是否与使用它注释的组件的生命周期相关联?如果那个组件超出了范围并且是GC,则该范围的死亡是什么?
还有一个相关的问题:假设我有一些依赖项,我希望将其范围扩展到两个活动之一。我是否需要创建两个单独的范围(即@MainActivityScope
和@SettingsActivityScope
),或者我可以使用我用于两者的通用活动范围(@ActivityScope
),但它表示两个独立的范围取决于如何使用?也许当我理解我的第一个问题时,这将有助于我理解这个问题的答案。
感谢。
答案 0 :(得分:4)
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实例,那么当活动被销毁时,Component(理想情况下)将无法访问并被收集。但是,就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
Unscoped意味着每次注射新实例。现在让我们试试子组件:
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在同一个整体(应用程序/单例)组件中共享
只要它们是单独层次结构的所有部分,您就可以拥有与您一样多的ActivityComponents,或者拥有尽可能多的@ActivityScoped组件。您可以选择创建@ActivityScoped MainActivityComponent和@ActivityScoped SettingsActivityComponent,或者创建一个知道如何注入每个元素的公共ActivityComponent。你可能不需要@MainActivityScope和@SettingsActivityScope,因为一个人不会从另一个人那里得到。重要的是,您为每个活动实例创建一个新的@ActivityScoped组件实例,这是Dagger保持范围一致所需的全部内容。