gpt4 book ai didi

java - Dagger 2 单例不工作

转载 作者:搜寻专家 更新时间:2023-10-30 21:10:37 25 4
gpt4 key购买 nike

使用 Dagger 2,我试图在单个范围内的多个位置注入(inject)一个单例对象。但是,我的解决方案似乎每次都创建一个新实例。

在这个测试项目中,我有一个初始化 DaggerModule 的 MainActivity。 DaggerModule 提供对象 Box 和 Cat,其中 Box 以 Cat 作为参数。我还在我的 MainActivity 中加入了 Cat。最后,我检查了两个注入(inject)的 Cat 变量的引用(分别在 Box 和 MainActivity 中),但它们不是同一个实例。

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

主要 Activity :

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

@Module
public class DaggerModule {

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

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

}

@Singleton
@Component(modules = { DaggerModule.class })
public interface DaggerComponent {

Cat provideCat();

Box provideBox();

}

public class Cat {

@Inject
public Cat() {
}

}

public class Box {

private Cat mCat;

@Inject
public Box(Cat cat) {
mCat = cat;
}

public Cat getCat() {
return mCat;
}

}

提前致谢!

编辑:如果 provideBox 接受 Cat 参数并使用它来创建 Box,而不是直接从 provideBox 中调用 provideCat,它就会工作。

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

对比

    // Works, same singleton injected.
@Provides
@Singleton
public Box provideBox(Cat cat) {
return new Box(cat);
}

在 MainActivity 中调用 provideCat 和在 DaggerModule 中的 provideBox 中调用有什么区别?会不会是 Dagger 编译器处理 DaggerModule 的方式与处理外部类的方式不同,如果我在其中调用 provideCat,注释就不会应用?

最佳答案

我想从 provideBox 中调用 provideCat 的原因是我对 Component 接口(interface)的误解。我误解了Component接口(interface)实际上并没有被Module实现,所以Module方法的参数不必在Component的相应方法中声明。如果是这样的话,它会迫使我在 MainActivity 的 provideBox 方法调用中创建 Cat 实例,而我想避免这种情况(因此直接在模块的 provideBox 方法中调用 provideCat)。事实上,在 Component 方法中声明参数甚至会使 Dagger 编译器无法编译。

但由于 Component 方法不带参数,解决方案是在需要的地方将实例作为参数注入(inject) Module 方法(而不是从 Module 本身内部调用相应的提供方法),并且只需要调用MainActivity 中组件的无参方法如下:

主要 Activity :

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

}

MainActivity 和 Box 的 Cat 单例实例现在相同,我不必从 MainActivity 中声明它们,但 Dagger 处理了这一切。成功!不过,仍然不确定为什么 provide 方法在从外部类调用时与从模块本身调用时的工作方式不同。

关于java - Dagger 2 单例不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29435586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com