作者:强伟2502859647 | 来源:互联网 | 2023-01-05 16:15
我正在努力了解@Reusable
Dagger范围的使用.从文档中我可以理解的是,如果提供程序的作用域@Singleton
或任何其他自定义作用域,则首先创建对象,然后在组件的整个生命周期中对其进行高速缓存.因此,对于并不总是需要相同实例或不经常使用的对象,这种方法最终会浪费内存.
但是如果我们选择一个非范围的提供者,每次它都会创建一个新实例,并且由于对象实例化很昂贵,特别是在Android等环境中,分配可能很昂贵,这可能会导致性能问题.
@Reusable
范围位于无范围和范围实例之间.从文档中
有时您希望限制实例化@Inject构造的类或调用@Provides方法的次数,但您不需要保证在任何特定组件或子组件的生命周期中使用完全相同的实例
它是如何工作的?假设我有一个可重用的提供程序,AppComponent
它不会总是给我相同的实例吗?
如果我在任何中注入相同的依赖项Subcomponent
,我将获得相同的实例吗?什么时候将为GC释放缓存的对象?
我尝试了一个示例,@Reusable
在我的AppComponent
模块中创建一个对象并从我的子组件中注入相同的对象.
我能看到的是它的表现完全一样@Singleton
.
我们可以从中获得哪些性能改进@Reusable
?
我们应该选择哪些可能的用例@Reusable
?
将所有无状态对象(无论我们是否获得相同的实例)都包括在内,例如Util类,Gson,Glide等,这是一个好主意@Reusable
吗?
1> David Medenj..:
我想指出,从@Reusable
v2.13开始仍处于测试阶段,因此可能会再次更改或删除.
tl; dr它的行为类似于变量范围,但不保证在任何给定时间都有单个实例.
它是如何工作的?假设我的AppComponent中有一个可重用的提供程序,它不会总是给我相同的实例吗?
Javadoc在这个问题上非常清楚:
一个范围,指示绑定返回的对象可能(但可能不会)重用.
当你想限制一个类型的条款数量时,@ Reusable很有用,但是没有特定的生命周期,只有一个实例.
它没有提供任何有关它如何工作的信息,你不应该依赖任何可能的实现,因为它们可能会改变,特别是当它仍然存在时@Beta
.
假设@Reusable
可以用于可以多次存在的对象,但是多个对象的实例化可能会更加昂贵,因此重新使用对象是有意义的.
虽然实施可能会改变,但预期用途不会改变.因此,如果您决定使用@Reusable
,则应确保对象的一个,两个或多个实例,无论在何处或是否被缓存都无关紧要.
哪些是可能的用例,我们应该更喜欢@Reusable?
将所有无状态对象(无论我们得到相同的实例都无关紧要)(例如Util类,Gson,Glide等)作为@Reusable进行范围化是一个好主意吗?
如上所述,您应该使用它,这对于一个可以重用的对象是有意义的,正如名称所暗示的那样.Gson是一个相当糟糕的例子,因为它使用了相当多的反射并且它的实例化非常昂贵,它应该是@Singleton
.Glide也不是一个很好的例子,因为它无论如何都将在内部使用Singleton模式.
的一个好处@Reusable
在@Singleton
是,你不要做一个关于作用域或组件之间的层次要求.确定对象的范围@Singleton
将意味着您的AppComponent将在其整个生命周期内保留该对象,而@Reusable
该对象可能只在子组件中创建,一直沿着依赖关系树创建并再次与其一起销毁.
我不会将它用于具有很少依赖性的对象,因为它们可以非常容易地创建,但是将它用于不保持任何状态并且需要更多设置的对象.
但它是如何工作的?
可重复使用是一种@Scope
得到一些特殊处理.您可以看到添加它的提交.
作为范围,注释的对象@Reusable
将保存在组件中.您可以查看第一个单元测试.它验证子组件将重新使用其父级提供程序(如果可用).这是你提到的行为,为什么它似乎没有区别@Singleton
.
与正常范围的区别在于Provider
使用.而不是使用ScopedProvider
,@Reusable
使用SimpleLazilyInitializedProvider
.它synchronized
在创建对象时省略了关键字,这可能会略微提升性能,但解释了为什么没有特定的生命周期,必须只有一个实例.
如果他们改变了@Reusable
未来的内部运作方式,我不会感到惊讶,但是现在知道它的作用范围可能有助于决定何时使用它.