以下代码创建&使用不同的活动共享注入的依赖项(ViewsApiEnd
)的相同对象,而不是为每个活动创建不同的。
@ActivityScope
@Component(dependencies = HttpComponent.class, modules = ViewsApiModule.class)
public interface ViewsApiComponent {
void inject(MainActivity activity);
void inject(SecondActivity activity2);
}
模块:
@Module
public class ViewsApiModule {
@Provides
@ActivityScope
public ViewsApiEnd providesGitHubInterface(Retrofit retrofit) {
return retrofit.create(ViewsApiEnd.class);
}
}
范围:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope{
}
完整资料来源:Github(如果有人可以分叉并更正范围issue,那将会有所帮助。还有用于验证对象创建的问题void logInstances()
如果我希望dagger2为不同的活动(ViewsApiComponent
创建不同的注入deps(ViewsApiEnd
)对象,我该如何声明MainActivity
SecondActivity
}})?
答案 0 :(得分:2)
我假设不同的对象是指不同的实例,而不是不同的实现。
关键是范围以及如何管理组件。特别是ViewsApiComponent
。
让我们从范围开始。匕首中的范围只是一个注释,告诉匕首在给定组件的生命周期中,只要需要使用给定范围注释的对象,提供的实例将始终相同。换句话说,在相同的组件范围内,依赖关系将是单例。
在您的代码中,此ActivityScope
是与ViewsApiEnd
绑定的范围。现在人们通常不了解范围是第一部分 - " ...只要组件是活动范围的依赖关系是单身"。基本上这就是说,如果你的组件实例保持不变,那么你所有的范围实例都是一样的。
在您的代码中就是这种情况,因为您将mViewsApiComponent
固定到应用程序类,而您永远不会重新创建它。所以在你的活动中这样做:
// ...
((MyApp) getApplication()).getGitHubComponent().inject(this);
// ...
您始终使用相同的组件,因此范围相同,因此ViewsApiEnd
的实例相同。
您需要确保作用域依赖项具有适当的范围处理。如果您希望每个活动的依赖项不同,那么您希望在每个活动的基础上管理负责此依赖关系的组件。
有不同的方法可以做到这一点。我认为在您的情况下最简单的方法是将ViewsApiComponent
的创建移动到您的活动中。确保在onDestroy
中使组件无效。像这样:
private ViewsApiComponent mViewsApiComponent;
@Override
public void onCreate() {
super.onCreate();
getComponent().inject(this);
}
@Overrides
public void onDestroy() {
super.onDestroy();
mViewsApiComponent = null;
}
private ViewsApiComponent getComponent() {
if (mViewsApiComponent == null) {
mViewsApiComponent = DaggerViewsApiComponent.builder()
.httpComponent(((MyApp) getApplication()).getNetComponent())
.build();
}
return mViewsApiComponent;
}
您甚至可以将此代码放在基本活动中,并在每个活动中从中继承。
需要注意的重要一点是,该组件现在由活动管理,或者更好地将其与其生命周期联系起来。这可确保组件在活动的生命周期内存在,并且所有范围内的依赖关系在该活动中都是相同的。对于另一个活动,将创建一个新组件并使用新的对象实例,但在活动中它们将保持不变。
现在我已经解释了所有这些只是为了试图帮助你解决组件和范围,但事实是你在组件的模块中提供的所有内容都是在整个应用程序的生命中应该确实是单例的对象。事实上,至少在我看来,你现在拥有它的方式是最正确的方法。
希望这有帮助