【发布时间】:2015-08-20 09:01:36
【问题描述】:
我有 F1 和 F2 类的对象,我想将它们注入到保留的 Fragment 中。我还有一个 A 类的对象,它依赖于 Activity,我希望它被注入到该 Activity 和附加到该 Activity 的片段管理器的保留片段中。我编写以下代码。一、Activity依赖的模块:
@Module
public class MainActivityModule {
private Activity mActivity;
public MainActivityModule(Activity activity) {
mActivity = activity;
}
@Provides
@ActivityScope
public A provideA() {
return new A(mActivity);
}
}
然后,相应的组件必须使A 对象对其依赖组件可用:
@ActivityScope
@Component(modules = {MainActivityModule.class})
public interface MainActivityComponent {
void inject(MainActivity activity);
// make the A object available to dependent components
A getA();
}
我也写了Fragment相关的模块:
@Module
public class FragmentModule {
@Provides
@FragmentScope
public F1 provideF1() {
return new F1();
}
@Provides
@FragmentScope
public F2 provideF2() {
return new F2();
}
}
及其对应的组件:
@FragmentScope
@Component(modules = {FragmentModule.class}, dependencies = {MainActivityComponent.class})
public interface FragmentComponent {
void inject(MyFragment presenter);
}
最后,我在Activity中注入了对A的依赖,在这里我还需要调用具体的生命周期方法。 Activity 还提供了获取组件的方法,以便 Fragment 在构建自己的组件时能够使用它:
// in MainActivity.onCreate
mActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(this))
.build();
mActivityComponent.inject(this);
mA.onCreate();
我也尝试在 Fragment 中注入对 A、F1、F2 的依赖项:
// in MyFragment.onCreate
FragmentComponent component = DaggerFragmentComponent.builder()
.fragmentModule(new FragmentModule())
.mainActivityComponent(((MainActivity) getActivity()).getComponent())
.build();
component.inject(this);
但是,由于 Fragment 被保留,当系统响应配置更改(例如设备旋转)而销毁并重新创建 Activity 时,Fragment 保持对旧 A 实例的引用,而新 Activity已经正确地重新创建了一个新的 A 实例来配合它。要解决这个问题,我必须创建FragmentComponent 并将依赖项注入MyFragment.onActivityCreated 而不是MyFragment.onCreate。另一方面,这意味着每次销毁和重新创建活动时都会重新创建F1 和F2 依赖项;但它们是 Fragment 范围的依赖项,因此它们应该遵循 Fragment 生命周期而不是 Activity 的。
因此,我的问题如下:是否可以在保留的 Fragment 中注入不同范围的依赖项?理想情况下,F1 和F2 依赖项应该注入MyFragment.onCreate,而A 依赖项应该注入MyFragment.onActivityCreated。我尝试使用两个不同的组件,但似乎无法执行部分注入。目前,我最终在MyFragment.onActivityCreated 中添加了对片段A 依赖项的显式重新分配,但这并不是真正的注入,你知道的。能否以更好的方式完成?
【问题讨论】:
-
注入不能很好地处理生命周期不受您控制的对象(如活动)。通常一个片段只能与它的父活动一起工作,所以你并没有真正从注入中受益。但是,对于单元测试,您可以提供
setA(A a)方法,以便您可以使用模拟/测试对象覆盖该值。另外:你为什么使用 2 个独立的组件并分别注入图表(而不是一个应用程序范围的组件,因此在应用程序启动时只有一个图表构建)? -
@Ogre_BGR 我知道这很难,这就是我在这里寻求帮助的原因。我看到的好处与减少进入 Activity 的代码量有关;它需要在其
A对象上包含与生命周期相关的调用,但由于该对象确实由 Fragment 使用,因此该代码应该保留在 Fragment 中,而不是 Activity 中。所以它与代码组织有关,而不是测试。我不能使用应用程序范围的组件,因为A(我没有完全控制)严格依赖于 Activity 实例(而不仅仅是 Context)。 -
你可以制作一个应用模块并从应用模块中获取所有实例
-
@GiulioPiancastelli 你能解决你的问题吗?我有同样的问题
-
我想你误解了我的意思。 Fragment 组件当然应该是更高级别范围的子组件,因此应该从其自身或更高范围注入它需要的任何内容。但是,如果您要使用保留的片段,那么片段将不再属于单个活动,因此将它们作为活动的子组件而是作为同级可能不合适。如果您不使用保留的片段,那么将片段作为活动的子组件非常适合。否则,请小心。
标签: android android-fragments dependency-injection dagger dagger-2