我想注入具有嵌套依赖项的Activity对象。所有依赖项都由Dagger模块管理。
我试图以三种不同的方式做到这一点。对我来说,最好的方法是第三,这实际上给我一个错误,我不完全理解。
你能解释一下为什么第三种方法不起作用吗?
public class Bar {
public void bar() {
Log.i("Bar", "bar");
}
}
public class MainActivity extends Activity {
@Inject
Foo foo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ObjectGraph.create(new MainModule()).inject(this);
ButterKnife.inject(this);
}
@OnClick(R.id.button)
void onButtonClick() {
foo.foo();
}
}
第一种方法正在运作 - Foo是一个接口的实现:
public interface IFoo {
public void foo();
}
public class Foo implements IFoo{
@Inject
Bar bar;
@Override
public void foo() {
bar.bar();
}
}
@Module(injects = MainActivity.class, library = true)
public class MainModule {
@Provides
@Singleton
Bar provideBar() {
return new Bar();
}
@Provides
@Singleton
IFoo provideFoo(Foo foo) {
return foo;
}
}
第二种方法正在运作 - Foo是普通类,但模块并不包含它:
public class Foo {
@Inject
Bar bar;
public void foo() {
bar.bar();
}
}
@Module(injects = MainActivity.class)
public class MainModule {
@Provides
@Singleton
Bar provideBar() {
return new Bar();
}
}
第三种方法抛出错误 - Foo是普通类,模块包含它:
Error:(12, 8) error: Unknown error java.lang.IllegalStateException thrown by javac in graph validation: Dependency cycle:
0. foo.Foo bound by @Singleton/ProvidesBinding[key=foo.Foo method=foo.MainModule.provideFoo()
0. foo.Foo
public class Foo {
@Inject
Bar bar;
public void foo() {
bar.bar();
}
}
@Module(injects = MainActivity.class, library = true)
public class MainModule {
@Provides
@Singleton
Bar provideBar() {
return new Bar();
}
@Provides
@Singleton
Foo provideFoo(Foo foo) {
return foo;
}
}
答案 0 :(得分:3)
此提供程序方法创建一个循环:
@Provides
@Singleton
Foo provideFoo(Foo foo) {
return foo;
}
您需要Foo
的实例来创建Foo
的实例,因此您永远无法获取实例。
建议的解决方案:
public class Foo {
private final Bar bar;
@Inject
public Foo(Bar bar) {
this.bar = bar;
}
public void foo() {
bar.bar();
}
}
@Module(injects = MainActivity.class, library = true)
public class MainModule {
@Provides
@Singleton
Bar provideBar() {
return new Bar();
}
@Provides
@Singleton
Foo provideFoo(Bar bar) {
return new Foo(bar);
}
}