这是关于如何存储生命周期应等于应用程序生命周期的@Singleton 作用域 Dagger 2 组件的第 N 个问题。
在使用 Dagger 2 的 Android 应用程序中,通常至少有一个 Component 是 @Singleton 范围的,并且应该在应用程序的整个生命周期中持续存在:由于这些要求,它通常被初始化并存储在自定义 Application 类中。
因为这个组件的实例必须在我们应用程序的所有部分都可以访问,所以我见过这样的代码:
public class App extends Application {
public static AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
}
这样就可以在其他任何地方访问:
App.appComponent.inject(this);
public class App extends Application {
private static AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
public static AppComponent getAppComponent() {
return appComponent;
}
}
这样就可以在其他任何地方访问:
App.getAppComponent().inject(this);
public class App extends Application {
private AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this)).build();
}
public AppComponent getAppComponent() {
return appComponent;
}
}
这样它只能从持有对 Context 的引用的类实例访问:
// From within an Activity.
((App) getApplication()).getAppComponent().inject(this);
// From within a Fragment.
((App) getActivity().getApplication()).getAppComponent().inject(this);
// From within any other class which holds a reference to a Context.
((App) context.getApplicationContext()).getAppComponent().inject(this);
最后一种方式使得将 Context 引用传递给任何愿意访问组件的类变得非常强制(即使该类出于任何其他目的不需要该 Context)。
恕我直言,必须“手动注入(inject)”一个 Context 实例才能访问注入(inject)器本身,这听起来有点违反直觉。
另一方面,许多人建议不要使用静态变量,但是:为什么?如果一个对象必须在应用程序的生命周期(这意味着 JVM 实例的整个生命周期)内保留在内存中,如果它存储在静态变量中会有什么问题?
其他人说静态的东西不能在测试中被模拟,这是真的,虽然我不确定我完全理解这个,因为它是 DI 模式,而不是注入(inject)器本身,它可以轻松模拟/测试,所以为什么会我们想模拟注入(inject)器本身吗?
这些替代方案的优缺点是什么?除了这里已经提到的之外,还有其他可能的替代方案吗?
最佳答案
对于 1 和 2,您使用的是静态引用。这是一个关于为什么要避免它们的好帖子
Why are static variables considered evil?
所以剩下的唯一选择就是第三个。这就是我在我的项目中使用的。 关于是否应该将上下文作为参数传递,取决于项目的体系结构以及设计 Dagger 依赖项的方式。我个人没有这个问题,因为我只注入(inject) Activity/fragment 。你能给我一个例子,你需要传递上下文来注入(inject)依赖吗?
关于java - Android 上的 Dagger 2。存储和访问 @Singleton 组件的不同方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39264599/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
让我们计算MRI范围内的类别:defcount_classesObjectSpace.count_objects[:T_CLASS]endk=count_classes用类方法定义类:classAdefself.foonilendend然后运行:putscount_classes-k#=>3请解释一下,为什么是三个? 最佳答案 查看MRI代码,每次你创建一个Class时,在Ruby中它是Class类型的对象,ruby会自动为这个新类创建“元类”类,这是另一个单例类型的Class对象。C函数调用(class.c)是:rb_define
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www