Java 匕首2单件不起作用

Java 匕首2单件不起作用,java,android,dependency-injection,dagger-2,Java,Android,Dependency Injection,Dagger 2,使用Dagger2,我试图在一个范围内的多个位置注入一个单例对象。然而,我的解决方案似乎每次都会创建一个新实例 在这个测试项目中,我有一个初始化DaggerModule的MainActivity。DaggerModule提供对象Box和Cat,Box将Cat作为参数。在我的主要活动中,我也养猫。最后,我检查了注入的两个Cat变量的引用(分别在框中和MainActivity中),但它们不是同一个实例 如果我在MainActivity中调用provideCat()两次,则会提供相同的实例 主要活动:

使用Dagger2,我试图在一个范围内的多个位置注入一个单例对象。然而,我的解决方案似乎每次都会创建一个新实例

在这个测试项目中,我有一个初始化DaggerModule的MainActivity。DaggerModule提供对象Box和Cat,Box将Cat作为参数。在我的主要活动中,我也养猫。最后,我检查了注入的两个Cat变量的引用(分别在框中和MainActivity中),但它们不是同一个实例

如果我在MainActivity中调用provideCat()两次,则会提供相同的实例

主要活动:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerModule daggerModule = new DaggerModule();
        DaggerComponent daggerComponent = Dagger_DaggerComponent.builder()
                .daggerModule(daggerModule).build();

        // Same Cat instance returned.
        Cat cat1 = daggerComponent.provideCat();
        Cat cat2 = daggerComponent.provideCat();
        Log.d("=== cat1: ", cat1.toString());
        Log.d("=== cat2: ", cat2.toString());

        // Different Cat instance returned. Why?
        Box box = daggerComponent.provideBox();
        Log.d("=== box cat: ", box.getCat().toString());
    }
}
Cat cat = daggerComponent.provideCat();
Box box = daggerComponent.provideBox();




提前谢谢

编辑: 如果provideBox接受Cat参数并使用该参数来创建框,而不是直接从provideBox中调用provideCat,则该方法有效

    // Doesn't work, new Cat instance created.
    @Provides
    @Singleton
    public Box provideBox() {
        return new Box(provideCat());
    }
vs


在main活动中调用provideCat与在DaggerModule中从provideBox中调用有什么区别?可能是Dagger编译器处理DaggerModule的方式与处理外部类的方式不同,并且如果我在其中调用provideCat,注释也不会应用?

我想从provideBox中调用provideCat的原因是我对组件接口的误解。我误解了组件接口实际上不是由模块实现的,因此模块方法的参数不必在组件的相应方法中声明。如果是这样的话,它会迫使我在MainActivity的provideBox方法调用中创建Cat实例,这是我想要避免的(因此直接在模块的provideBox方法中调用provideCat)。事实上,在组件方法中声明参数甚至使Dagger编译器无法编译

但由于组件方法不接受参数,解决方案只是在需要时将实例作为参数注入模块方法中(而不是从模块本身中调用相应的提供方法),并且只需从MainActivity调用组件的无参数方法,如下所示:

主要活动:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerModule daggerModule = new DaggerModule();
        DaggerComponent daggerComponent = Dagger_DaggerComponent.builder()
                .daggerModule(daggerModule).build();

        // Same Cat instance returned.
        Cat cat1 = daggerComponent.provideCat();
        Cat cat2 = daggerComponent.provideCat();
        Log.d("=== cat1: ", cat1.toString());
        Log.d("=== cat2: ", cat2.toString());

        // Different Cat instance returned. Why?
        Box box = daggerComponent.provideBox();
        Log.d("=== box cat: ", box.getCat().toString());
    }
}
Cat cat = daggerComponent.provideCat();
Box box = daggerComponent.provideBox();
组成部分:

Cat provideCat();
Box provideBox(); <- no arguments
Cat provideCat();

Box provideBox();行为不同的原因是实例管理由组件实现而不是模块处理。当您直接调用该方法时,它只会像调用任何其他Java方法一样调用它,但是当您让组件将依赖项连接在一起时,它将使用
dagger.internal.ScopedProvider
来确保只有一个实例。另外,对于
@Inject
类型,您可以只注释该类(在这种情况下,
Cat
Box
)直接使用
@Singleton
并避免使用
@提供的方法。感谢您提供的信息和提示!有一个非常类似的问题。这让我省去了很多麻烦。谢谢!是的。对于调用provder方法和Injector方法之间的区别以及为什么使用这两种方法,我有点困惑。仍然不是100%在上面。
    // Works, same singleton injected.
    @Provides
    @Singleton
    public Box provideBox(Cat cat) {
        return new Box(cat);
    }
Cat cat = daggerComponent.provideCat();
Box box = daggerComponent.provideBox();
Cat provideCat();
Box provideBox(); <- no arguments
@Module
public class DaggerModule {

    @Provides
    @Singleton
    public Cat provideCat() {
        return new Cat();
    }

    @Provides
    @Singleton
    public Box provideBox(Cat cat) { <- arguments
        return new Box(cat);
    }

}