[英]Dagger 2 scope and subcomponents
我正在嘗試使我的應用程序更好,代碼更易於使用Dagger2
我抓住了一般的想法,但仍然無法弄清楚范圍是如何管理Dagger2
我注入匕首到我的項目(聽起來很有趣)。 我創建了ApplicationComonent
組件,它在我的項目中完美運行。 這是我的代碼。
@Singleton
@Component(modules = {
ApplicationModule.class,
ThreadingModule.class,
NetworkModule.class,
DatabaseModule.class,
ServiceModule.class,
ParseModule.class,
PreferencesSessionModule.class})
public interface ApplicationComponent {
ActivityComponent activityComponent(ActivityModule activityModule);
void inject(BaseActivity baseActivity);
void inject(MainAppActivity mainAppActivity);
void inject(MyApplication application);
void inject(BaseFragment baseFragment);
void inject(MyService service);
void inject(RegistrationIntentService service);
}
我在MyApplication
類中創建我的組件實例
private void initializeAndInjectComponent() {
mApplicationComponent =
DaggerApplicationComponent
.builder()
.threadingModule(new ThreadingModule(1))
.applicationModule(new ApplicationModule(this))
.networkModule(new NetworkModule(
MyService.API_SERVER_BASE_URL,
MyService.TIMEOUT))
.build();
mApplicationComponent.inject(this);
}
我可以獲得組件以便在我的Activities
注入
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().inject(this);
一切都很完美。
要添加每個方法以及模塊類,請使用@Singleton
范圍進行注釋,所有模塊都與ApplicationComponent
相關
現在我想要更好地依賴關系,我已經看到很多自定義范圍的例子,如@PerActivity
, @PerFragment
。 我有很多問題,但稍后會有這個問題。
所以我創建了ActivityComponent
@PerActivity
@Subcomponent(
modules = {
NetworkServiceModule.class,
ActivityModule.class,
PermissionModule.class
})
public interface ActivityComponent {
Activity activity();
void inject(BaseActivity baseActivity);
}
所有模塊都是這樣的
@PerActivity
@Module
public class ActivityModule {
private Activity mActivity;
public ActivityModule(Activity activity) {
this.mActivity = activity;
}
@Provides
@PerActivity
Activity provideActivity() {
return this.mActivity;
}
}
我的BaseActivity
有以下依賴BaseActivity
// Dependencies from ApplicationComponent
@Inject
protected ApplicationSettingsManager mApplicationSettingsManager;
@Inject
protected ScheduledThreadPoolExecutor mPoolExecutor;
// Dependencies from ActivityComponent
@Inject
protected SpiceManager mSpiceManager;
@Inject
protected PermissionController mPermissionController;
在我的onCreate()
方法中,我注入如下
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().activityComponent(new ActivityModule(this)).inject(this);
在創建子組件ActivityComponent
之前,它是
MyApplication application = MyApplication.get(this);
application.getApplicationComponent().inject(this);
現在我收到了一個錯誤
Error:(34, 10) error: com.octo.android.robospice.SpiceManager cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
BaseActivity.mSpiceManager
[injected field of type: com.octo.android.robospice.SpiceManager mSpiceManager]
我無法弄清楚問題在哪里,我錯過了什么。 我對dagger2中的范圍有疑問。
除了@Singleton
所有東西都被Dagger 2忽略了,對嗎? 我不明白組件的生命是如何管理的? 我只有一個想法
當您使用@Singleton
注釋時,dagger會在整個應用程序生命周期中存在的某個靜態池中創建對象,並且在銷毀JVM進程(dalvik VM,ART)實例時將被銷毀。
當你使用任何其他注釋只是為了讓你作為開發人員更好地維護代碼, @PerActivity
, @PerFragment
只是自定義注釋而已。 如果你在Application類中放置@PerFragment
組件,只要應用程序存在,它就會存在。 我對嗎 ?
所以我理解這一點,如果dagger找到@Singleton
注釋,它將在第一次創建時添加對組件的靜態引用,並且在任何其他注釋的情況下,它將不保持對組件的引用。
對於上述問題的任何幫助,我將非常感激。
UPDATE
謝謝David Medenjak
的答案,我對Dagger2
有了更深入的Dagger2
。
我剛剛發現了問題,就我現在使用單獨的Activity
組件而言,我忘記了ApplicationComponent
兩行並將我的MainActivity
inejction更改為ActivityComponent
而不是ApplicationComponent
,所以肯定它無法解析子組件的依賴關系。
void inject(BaseActivity baseActivity);
void inject(MainAppActivity mainAppActivity);
現在一切都很完美,我喜歡Dagger2
和分離的建築。
有點激進,但為了簡化事情: 所有范圍注釋都只是語法糖 - 包括@Singleton
。
范圍主要是提供編譯時檢查。 循環依賴關系,或者您可能錯過的事情的錯誤。 @Singleton
就像任何其他范圍一樣,唯一的區別是它是一個已經存在的注釋,你不必自己創建它。 您可以使用@MySingleton
代替。
[...] dagger正在一個靜態池中創建對象,該對象將在整個應用程序生命周期中存在
不,Dagger 什么都不做 。 你有組件對象。 這些組件包含由模塊創建的對象。 如果組件中的對象具有組件的范圍,則只會在該組件中創建一次。 如果您決定創建2個AppComponent
對象,則每個@Singleton
注釋對象將有2個對象,每個對象位於其組件中。 這就是您應該保留對組件的引用的原因。 我見過或使用的大多數實現因此將其AppComponent
保留在其Application
。 如果你這樣做,你可以像單身一樣使用它 - 它仍然只是一個POJO。
[...]你將@PerFragment組件放在Application類中,只要應用程序存在,它就會存在。
是。 如上段所述,它只是一個對象。 保留參考,保留對象。 扔掉它或創建一個新的對象(在此組件/范圍內定義)。 你應該盡管跟不上活動或片段范圍的部件的任何地方,除了分別在活動或片段,因為讓他們如在你的應用程序組件將最有可能導致內存泄漏。 (如果沒有,您可能不需要活動或片段范圍。)
如果dagger找到
@Singleton
注釋,它將在第一次創建時添加對組件的靜態引用,並且在任何其他注釋的情況下,它將不保持對組件的引用。
再一次,沒有。 沒什么是靜止的。 普通的舊java對象。 您可以將多個@Singleton
組件與其自己的對象一起使用,但您可能不應該這樣做(盡管這是使得檢測可能/易於交換組件的原因。)
沒有@Inject構造函數或@ Provide-或@ Produces-annotated方法,不能提供SpiceManager。
這意味着您嘗試注入對象的組件無法找到生成或提供SpiceManager
任何方法。 確保您從AppComponent或其他地方提供,不遺漏任何注釋等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.