匕首2范围生命周期

时间:2017-03-24 04:20:56

标签: java android dependency-injection dagger-2

我目前正在熟悉dagger2和依赖注入。我认为我对基础知识有一定的把握,但我无法理解范围。有两件事我想帮助理解。 A)关于范围生存期,B)关于范围重复使用多次。

当谈到范围时,范围的生​​命周期的想法总是会出现。我认为,对于在给定范围内提供的依赖关系,将提供单个实例,而该范围是“活着的”。究竟是什么决定了一个范围是活着还是死了?是否与使用它注释的组件的生命周期相关联?如果那个组件超出了范围并且是GC,则该范围的死亡是什么?

还有一个相关的问题:假设我有一些依赖项,我希望将其范围扩展到两个活动之一。我是否需要创建两个单独的范围(即@MainActivityScope@SettingsActivityScope),或者我可以使用我用于两者的通用活动范围(@ActivityScope),但它表示两个独立的范围取决于如何使用?也许当我理解我的第一个问题时,这将有助于我理解这个问题的答案。

感谢。

1 个答案:

答案 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保持范围一致所需的全部内容。