Android dagger2模块无法注入其他模块
Android dagger2 module cannot be injected into other module
我正在尝试学习如何使用 dagger2。您是否应该为您拥有的每个模块制作一个组件(然后在 "super-components" 中组合组件)?
我有 2 个可以工作的模块,它们曾经有单独的组件。然后我添加了一个额外的模块(没有组件),在新模块中我的@Inject 似乎不起作用。
我怎样才能将我的 AppModule 注入到我的新 GyroModule 中?
我的新 "Gyro" 模块:
@Module
public class GyroModule implements SensorEventListener {
@Inject AppModule _appModule; // NULL
private SensorEvent _lastReading;
private SensorManager _sensorManager;
private Sensor _gyro;
@Inject
public GyroModule() {
initialize();
}
@Provides
@Singleton
public GyroModule provideGyroModule() {
return this;
}
我的主要活动:
public class MainActivity extends LocationAwareActivity {
@Inject PointOfInterestModule pointOfInterestModule; // OK
@Inject LocationModule locationModule; // OK
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((AllTheLocateApplication) getApplication()).getAppComponent().inject(this);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, AugmentedActivity.class);
startActivity(intent);
}
}
我的 "god" 组件(也是应用程序中的唯一组件):
@Singleton
@Component(modules={AppModule.class,
PointOfInterestModule.class,
LocationModule.class,
GyroModule.class})
public interface IAppComponent {
void inject(AllTheLocateApplication application);
void inject(MainActivity mainActivity);
void inject(AugmentedActivity augmentedActivity);
void inject(AppModule appModule);
void inject(PointOfInterestModule pointOfInterestModule);
void inject(LocationModule locationModule);
void inject(GyroModule gyroModule);
}
我的 AppModule
@Module
public class AppModule {
AllTheLocateApplication mApplication;
public AppModule(AllTheLocateApplication application) {
mApplication = application;
}
public AllTheLocateApplication getApplication() {
return mApplication;
}
@Provides
@Singleton
AppModule providesAppModule() {
return this;
}
}
Are you supposed to make a component for every single module you have [...]
没有
[...] (and then combine components in "super-components")?
没有
模块应该是你的 B 计划,并且——明确地说——不惜一切代价避免,除非真的有必要。尽管有 3 个你需要使用它们的原因:
- 无法使用构造函数注入创建依赖项,
- 依赖项需要在创建时进一步初始化
- 依赖项正在实现接口,您正在提供实现
如果至少其中一项不成立,请不要使用模块。
注射
模块与注入无关。它们不——也不应该——包含您的业务逻辑。 他们所做的只是提供那些无法访问或注入构造函数的对象。它们无法注入,也不会被注入。如果一个对象依赖于另一个对象,则将其作为参数放入方法中。如果你不想自己调用构造函数,dagger 会为你创建模块,因为有一个无参数的构造函数。
initialize()
方法不应该是模块的一部分。如果您必须提供 A 并且 A 需要,它应该如下所示:
@Provides
provideA(B b) {
A a = new A();
a.setB(b);
a.doMoreInitializationThatMustBeDoneNow();
return a;
}
B 是从同一模块、不同模块、父组件、组件依赖项还是通过构造函数注入提供的,与您无关。模块不需要相互了解,dagger 只会用 B 调用你的方法。然后你只需要 return A.
我不知道你想用你的代码示例做什么。模块 不是 业务逻辑的一部分。它们提供 依赖项。您应该 而不是 依赖业务逻辑中的模块。您也不应该包含 getter、setter 或更新任何对象。模块创建一个对象并对其进行初始化。他们不会以任何其他方式与之交互。
通过创建单个 java 文件来玩一下 dagger。添加一些模块。放入您尝试注入一些依赖项的 class 。您可以看到事物是如何编译(或不编译)的。也许可以尝试阅读更多有关 Dagger 的教程,以便更好地理解核心概念。
我正在尝试学习如何使用 dagger2。您是否应该为您拥有的每个模块制作一个组件(然后在 "super-components" 中组合组件)?
我有 2 个可以工作的模块,它们曾经有单独的组件。然后我添加了一个额外的模块(没有组件),在新模块中我的@Inject 似乎不起作用。
我怎样才能将我的 AppModule 注入到我的新 GyroModule 中?
我的新 "Gyro" 模块:
@Module
public class GyroModule implements SensorEventListener {
@Inject AppModule _appModule; // NULL
private SensorEvent _lastReading;
private SensorManager _sensorManager;
private Sensor _gyro;
@Inject
public GyroModule() {
initialize();
}
@Provides
@Singleton
public GyroModule provideGyroModule() {
return this;
}
我的主要活动:
public class MainActivity extends LocationAwareActivity {
@Inject PointOfInterestModule pointOfInterestModule; // OK
@Inject LocationModule locationModule; // OK
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((AllTheLocateApplication) getApplication()).getAppComponent().inject(this);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, AugmentedActivity.class);
startActivity(intent);
}
}
我的 "god" 组件(也是应用程序中的唯一组件):
@Singleton
@Component(modules={AppModule.class,
PointOfInterestModule.class,
LocationModule.class,
GyroModule.class})
public interface IAppComponent {
void inject(AllTheLocateApplication application);
void inject(MainActivity mainActivity);
void inject(AugmentedActivity augmentedActivity);
void inject(AppModule appModule);
void inject(PointOfInterestModule pointOfInterestModule);
void inject(LocationModule locationModule);
void inject(GyroModule gyroModule);
}
我的 AppModule
@Module
public class AppModule {
AllTheLocateApplication mApplication;
public AppModule(AllTheLocateApplication application) {
mApplication = application;
}
public AllTheLocateApplication getApplication() {
return mApplication;
}
@Provides
@Singleton
AppModule providesAppModule() {
return this;
}
}
Are you supposed to make a component for every single module you have [...]
没有
[...] (and then combine components in "super-components")?
没有
模块应该是你的 B 计划,并且——明确地说——不惜一切代价避免,除非真的有必要。尽管有 3 个你需要使用它们的原因:
- 无法使用构造函数注入创建依赖项,
- 依赖项需要在创建时进一步初始化
- 依赖项正在实现接口,您正在提供实现
如果至少其中一项不成立,请不要使用模块。
注射
模块与注入无关。它们不——也不应该——包含您的业务逻辑。 他们所做的只是提供那些无法访问或注入构造函数的对象。它们无法注入,也不会被注入。如果一个对象依赖于另一个对象,则将其作为参数放入方法中。如果你不想自己调用构造函数,dagger 会为你创建模块,因为有一个无参数的构造函数。
initialize()
方法不应该是模块的一部分。如果您必须提供 A 并且 A 需要,它应该如下所示:
@Provides
provideA(B b) {
A a = new A();
a.setB(b);
a.doMoreInitializationThatMustBeDoneNow();
return a;
}
B 是从同一模块、不同模块、父组件、组件依赖项还是通过构造函数注入提供的,与您无关。模块不需要相互了解,dagger 只会用 B 调用你的方法。然后你只需要 return A.
我不知道你想用你的代码示例做什么。模块 不是 业务逻辑的一部分。它们提供 依赖项。您应该 而不是 依赖业务逻辑中的模块。您也不应该包含 getter、setter 或更新任何对象。模块创建一个对象并对其进行初始化。他们不会以任何其他方式与之交互。
通过创建单个 java 文件来玩一下 dagger。添加一些模块。放入您尝试注入一些依赖项的 class 。您可以看到事物是如何编译(或不编译)的。也许可以尝试阅读更多有关 Dagger 的教程,以便更好地理解核心概念。