对我们最有效的是使用辅助注射。
根据具体情况,我们在活动本身、包中(用于构建该包中的所有活动)或在 ActivityMapper 中定义活动工厂。
public class MyActivity extends AbstractActivity {
private final MyView view;
@Inject
MyActivity(MyView view, @Assisted MyPlace place) {
this.view = view;
...
}
...
}
public class MyActivityMapper implements ActivityMapper {
public interface Factory {
MyActivity my(MyPlace place);
FooActivity foo(FooPlace place);
...
}
// using field injection here, feel free to replace by constructor injection
@Inject
private Factory factory;
@Overrides
public Activity getActivity(Place place) {
if (place instance MyPlace) {
return factory.my((MyPlace) place);
} else if (place instance FooPlace) {
return factory.foo((FooPlace) place);
}
...
}
}
// in the GinModule:
install(new GinFactoryModuleBuilder().build(MyActivityMapper.Factory.class));
顺便说一句,要使方法注入起作用,您仍然必须通过 GIN 创建活动,因此您会遇到与构造函数注入相同的问题。没有魔法,GIN 不会神奇地注入它不知道甚至不知道它们何时被实例化的类。您可以通过向 Ginjector 添加方法来显式触发方法注入,但我不推荐它(您的代码将取决于 Ginjector,如果可以的话,您应该避免这种情况):
interface MyGinjector extends Ginjector {
// This will construct a Foo instance and inject its constructors, fields and methods
Foo foo();
// This will inject methods and (non-final) fields of an existing Bar instance
void whatever(Bar bar);
}
...
Bar bar = new Bar("some", "arguments");
myGinjector.whatever(bar);
...
最后一句话:我不会将 place 对象直接传递给活动。尝试将地点和活动解耦,这允许您通过更改“外壳”布局和您的活动映射器。要真正将它们解耦,您必须构建某种导航器,这将抽象您的placeController.goTo()
调用,以便您的活动永远不会处理地点。