有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Dagger在注入嵌套依赖项时抛出IllegalStateException

我想注入到具有嵌套依赖关系的活动对象中。所有依赖项都由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;
    }

}

共 (1) 个答案

  1. # 1 楼答案

    此提供程序方法创建一个循环:

    @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);
        }
    
    }