gpt4 book ai didi

java - 在 Dagger 2 中使用 AndroidInjections 贡献模块(抽象类)作为子组件

转载 作者:行者123 更新时间:2023-11-29 02:33:43 25 4
gpt4 key购买 nike

我研究 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...

您如何在日志中看到,ApllicationMainActivity 接收实用程序类的不同实例。我想将 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/

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