我研究 Dagger 2 并尝试了解如何将其附加到现有项目中。现在我遇到了以下将依赖项注入(inject) BroadcastReceivers
的问题。我不能使用 DaggerReceiver
因为我的接收器已经扩展了另一个类。要在 BroadcastReceivers
中使用 AndroidInjection
,我应该将 DispatchingAndroidInjector
注入(inject)到 Application
类中。我不想将带有 AndroidInjection
贡献者的模块包含到主要依赖关系图中,所以,据我所知,我应该将它放在 Application
类的专用组件中,但正因为如此出现单例重复。
这是我的例子(GitHub repo)
为 MainActivity
和其他类提供依赖的类
AppModule.class
@Module
public class AppModule {
Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
Application providesApplication() {
return mApplication;
}
}
UtilityModule.class
@Module
public class UtilityModule {
@Singleton
@Provides
FirstUtilityClass providesFirstUtility(Application app) {
return new FirstUtilityClass(app);
}
@Singleton
@Provides
SecondUtilityClass providesSecondUtility(Application app) {
return new SecondUtilityClass(app);
}
}
MainComponent.class
@Singleton
@Component(modules = { AppModule.class, UtilityModule.class })
public interface MainComponent {
void inject(MainActivity activity);
}
向Application
类提供DispatchingAndroidInjector
的类
ReceiversModule.class
@Module
public abstract class ReceiversModule {
@ContributesAndroidInjector
abstract FirstReceiver contributesFirstReceiver();
@ContributesAndroidInjector
abstract SecondReceiver contributesSecondReceiver();
}
ReceiversComponent.class
@Singleton
@Component(modules = { AppModule.class, UtilityModule.class, ReceiversModule.class })
public interface ReceiversComponent {
void inject(MyApplication application);
}
注入(inject)...
MyApplication.class
public class MyApplication extends Application implements HasBroadcastReceiverInjector {
@Inject DispatchingAndroidInjector<BroadcastReceiver> mInjector;
@Inject FirstUtilityClass mFirstUtility;
@Inject SecondUtilityClass mSecondUtility;
MainComponent mMainComponent;
@Override
public void onCreate() {
AppModule appModule = new AppModule(this);
mMainComponent = DaggerMainComponent.builder().appModule(appModule).build();
// I should build new component only for Application class, because DispatchingAndroidInjector not required for another targets
DaggerReceiversComponent.builder().appModule(appModule).build().inject(this); // Here created new scope
super.onCreate();
// do something
mFirstUtility.doFistThings(getClass().getSimpleName());
mSecondUtility.doSecondThings(getClass().getSimpleName());
}
public MainComponent getMainComponent() {
return mMainComponent;
}
@Override
public AndroidInjector<BroadcastReceiver> broadcastReceiverInjector() {
return mInjector;
}
}
MainActivity.class
public class MainActivity extends AppCompatActivity {
@Inject FirstUtilityClass mFirstUtility;
@Inject SecondUtilityClass mSecondUtility;
@Override
protected void onCreate(Bundle savedInstanceState) {
((MyApplication) getApplication()).getMainComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Do something
mFirstUtility.doFistThings(getClass().getSimpleName());
mSecondUtility.doSecondThings(getClass().getSimpleName());
// Sending broadcasts here
}
}
Logcat 输出
FirstUtilityClass1: doing first things from MyApplication...
SecondUtilityClass1: doing second things from MyApplication...
FirstUtilityClass2: doing first things from MainActivity...
SecondUtilityClass2: doing second things from MainActivity...
FirstUtilityClass1: doing first things from FirstReceiver...
SecondUtilityClass1: doing second things from SecondReceiver...
您如何在日志中看到,Apllication
和 MainActivity
接收实用程序类的不同实例。我想将 ReceiversComponent
作为 MainComponent
的子组件。但是 ReceiversModule
是抽象的,我不能将它动态地添加到现有的组件实例中。
MainComponent.class
@Singleton
@Component(modules = { AppModule.class, UtilityModule.class })
public interface MainComponent {
ReceiversComponent with(ReceiversModule module);
void inject(MainActivity activity);
}
ReceiversComponent.class
@Subcomponent(modules = { ReceiversModule.class })
public interface ReceiversComponent {
void inject(MyApplication application);
}
然后在 MyApplication
中:
// It does not work because I can't create ReceiverModule instance :(
mMainComponent.with(new ReceiversModule()).inject(this);
如何将 ReceiversComponent
用作 MainComponent
的子组件?
我很清楚我做错了什么,但我就是不明白在哪里。也许有另一种方法可以解决我的问题?
最佳答案
我刚刚找到了答案!
由于我的 ReceiversModule
类有一个没有参数的默认构造函数,所以在 MainComponent
接口(interface)中描述子组件时,我可以跳过它作为参数:
MainComponent.class
@Singleton
@Component(modules = { AppModule.class, UtilityModule.class })
public interface MainComponent {
ReceiversComponent withReceiversModule(); // Here is the reference to the subcomponent with abstract module
void inject(MainActivity activity);
}
MyApplication.class
@Override
public void onCreate() {
AppModule appModule = new AppModule(this);
mMainComponent = DaggerMainComponent.builder().appModule(appModule).build();
mMainComponent.withReceiversModule().inject(this); // It's works!!! :)
super.onCreate();
// do something
mFirstUtility.doFistThings(getClass().getSimpleName());
mSecondUtility.doSecondThings(getClass().getSimpleName());
}
可能有人会觉得这是小事,但我花了好几天才搞定。我很高兴,因为我的代码变得更简洁了。感谢大家!
关于java - 在 Dagger 2 中使用 AndroidInjections 贡献模块(抽象类)作为子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48205344/