2016-08-13 84 views
11

我可以知道@Singleton VS static是否提供在dagger2?不同@Singleton&static @Provides in dagger2

@Provides static User currentUser(AuthManager authManager) { 
    return authManager.currentUser(); 
} 

@Provides @Singleton User currentUser(AuthManager authManager) { 
    return authManager.currentUser(); 
} 

回答

19

这些是非常不同的属性,你可以独立拥有一个或另一个。所有这些都是有效的:

@Provides User currentUser(...) {} 
@Provides static User currentUser(...) {} 
@Provides @Singleton User currentUser(...) {} 
@Provides @Singleton static User currentUser(...) {} 

要设置阶段,@Provides User法说,“这个组件或它的依赖,调用此方法@Provides每次你需要用户的时间。”通常,该方法每次都会返回一个新实例,而Dagger不会保存或缓存该实例。

@Singleton范围,这是一种奇特的方式说生命周期策略策略多久创建一个新的实例的例子。 @Provides @Singleton User说“对于这个组件或依赖关系,只需调用一次这个@Provides方法,并保存结果”。 @Singleton恰好是内置的常见情况,但您也可以想象创建@UserScope(始终为此用户返回相同的实例),或者在Android中为@FragmentScope@ActivityScope

针对您的特殊情况下,你可能不希望@Singleton,因为它会指示你的组件保存缓存从AuthManager值。如果用户值可能会在应用程序的整个生命周期中发生变化,则组件不会反映该值。 (在这种情况下,你也想确保注入Provider<User>,这将更新,而不是User它不会。)

离开作用域落后了片刻,static行为正是你希望它在Java中的方法:如果某个方法不需要任何实例状态,则可以使其成为static,并且虚拟机可以在不准备任何实例状态的情况下调用它。在您生成的Component实现中,Dagger将自动调用static方法,并将模块实例中的实例方法自动传入您的组件;在Android中这会导致性能的显着提高。由于您在currentUser方法中不使用任何实例状态,因此可以很容易地将其制作为static

延伸阅读:

+2

那么大多数时候,依赖方法应该被标记为'static'吧?因为他们很少有内部状态。 – hqt

+0

@hqt是的,绑定很少是有状态的,所以'@ Provide'实现通常应该是'static' - 特别是适当使用['@ BindsInstance'](https://google.github.io/dagger/api /latest/dagger/BindsInstance.html)的实例绑定,否则它们将在模块中声明。对于这个问题,如果你的静态'@Processor'方法只是'@Provides B provideB(A a){return a; }',跳过'static'并直接转到['@ Binds'](https://google.github.io/dagger/api/latest/dagger/Binds.html),以获得最佳性能。 –

+0

也许是一个noob问题,但你怎么能在Kotlin中应用这个? – Entreco

2

使用@Singleton注释在整个应用程序生命周期中只会创建一个User对象实例。

static on @Provides最近引入的方法使得方法的调用速度提高了15%到20%,如here所述。如果我们多次调用这个方法,将会有多个User对象的实例。

+1

我的回答也是dagger2,你可以检查出https://开头youtu.be/iwjXqRlEevg?t=5m9s为更清晰 – shekar

+0

如果我同时拥有@Singleton和静态? –