如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象? [英] How do you re-inject an android object, (Service, Activity...) being injected into by an AndroidInjector, into other objects?
问题描述
我有一个具有DaggerServiceComponent的服务,该服务将成功注入所有服务依赖项。
I have a Service that has a DaggerServiceComponent that will inject all of the Services dependencies successfully.
问题是我还有一个ServiceManager类,需要一个引用服务以管理服务任务。例如,
The problem is that I also have a ServiceManager class, which needs a reference to the Service in order to "Manage" service tasks. i.e.
应用
public class ApplicationBase extends Application implements HasServiceInjector {
@Inject
DispatchingAndroidInjector<Service> dispatchingAndroidServiceInjector;
protected void setupServiceComponent(Context context) {
ServiceContextModule serviceContextModule = new ServiceContextModule(context);
ServiceComponent serviceComponent = DaggerServiceComponent.builder().serviceContextModule(serviceContextModule).build();
serviceComponent.inject(this);
}
@Override
public AndroidInjector<Service> serviceInjector() {
return dispatchingAndroidServiceInjector;
}
}
组件
@Singleton
@Component(modules = { /* modules */})
public interface ServiceComponent extends AndroidInjector<ApplicationBase > {
ServiceManager provideServiceManager();
void inject(ApplicationBase appBase);
// ..
}
模块
@Module
public abstract class MediaPlaybackServiceModule {
@ContributesAndroidInjector
abstract MediaPlaybackService provideMediaPlaybackService();
}
MediaPlaybackService
MyService
MediaPlaybackService MyService
public class MediaPlaybackService extends MediaBrowserServiceCompat {
// ...
private ServiceManager serviceManager;
@Override
public void onCreate() {
init();
super.onCreate();
// ...
}
/**
* TO BE CALLED BEFORE SUPER CLASS
*/
private void init() {
AndroidInjection.inject(this);
serviceManager.setMediaPlaybackService(this);
}
//...
// declaration of other dependencies
}
如果您查看我目前的工作,我会手动向setter方法添加一个调用,以在成功注入的ServiceManager类中设置服务引用。
If you look at what I currently do at the moment, I manually add a call to the setter method to set "service" reference in the ServiceManager class which was successfully injected.
服务管理器类如下:
public class ServiceManager {
@Inject
public ServiceManager(MediaSessionAdapter mediaSession,
MyNotificationManager myNotificationManager) {
this.mediaSession = mediaSession;
this.notificationManager = myNotificationManager;
}
// BODY OF CLASS
public void setMediaPlaybackService(MediaPlaybackService mediaPlaybackService) {
this.service = mediaPlaybackService;
}
}
但我理想上希望拥有服务管理器构造函数看起来像
but I would ideally like to have the service manager constructor to look like
@Inject
public ServiceManager(MediaPlaybackService mediaPlaybackService, MediaSessionAdapter mediaSession,
MyNotificationManager myNotificationManager) {
this.service = mediaPlaybackService;
this.mediaSession = mediaSession;
this.notificationManager = myNotificationManager;
}
我需要对dagger2代码进行哪些更改才能实现
What changes do I need to make do my dagger2 code to be able to achieve this?
注意:为简单起见,我删除了应用程序中使用的多余代码,但可以在此处
NOTE: for simplicity I have removed the extra code used in the application, but it can be found here
推荐答案
因此,对于所有面临与自己相似的问题的人,我已经使用dagger-android进行了大量实验,发现它简单得多请执行以下操作:
So for all those who are facing a similar problem to myself I've been do a lot of experimentation with dagger-android and found it a lot simpler to do the following:
1)将活动抽象化
public abstract MainActivity extends AppCompatActivity {
...
abstract void initDependencies();
...
@Inject
public void setMyDependency(MyDependency myDependency) { ... }
}
2)创建一个子类来初始化您的依赖项,从而删除Activity中的匕首依赖项
2) Make a subclass to initialise your dependencies hence removing a dagger dependency in your Activity
public MainActivityProduction extends MainActivity {
@Override
void initDependencies() {
DaggerMainActivityComponent.factory().create(..., this)
.inject(this);
}
@Override
public void onCreate() {
initDependencies();
super.onCreate();
}
}
请注意,这允许使用单独的组件根据dagger文档中的建议进行测试 https://dagger.dev/testing 即
Note this allows for a separate component that could be used for testing as recommended in the dagger documentation https://dagger.dev/testing i.e.
public MainActivityTesting extends MainActivity {
@Override
void initDependencies() {
DaggerMainActivityTestingComponent.factory().create(..., this)
.inject(this);
}
@Override
public void onCreate() {
initDependencies();
super.onCreate();
}
}
3)因此,您的组件应如下所示:
3) Your component would therefore look like:
@Component(modules = { /* modules */})
public interface MainActivityComponent {
...
@Component.Factory
interface Factory {
MainActivityComponent create(...,
@BindsInstance MainActivity);
}
}
意味着您可以使用任何模块引用您的MainActivity
meaning that you can have any module refer to your MainActivity
@Module
public class MyDependencyModule {
@Provides
public MyDependency providesMyDependency(MainActivity MainActivity) {
return new MyDependency(mainActivity);
}
}
此解决方案:
- 使样板设置代码与主代码脱钩
- 允许轻松注入测试实现
- 删除对Application类的依赖关系以设置依赖关系。
这篇关于如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!