如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象? [英] How do you re-inject an android object, (Service, Activity...) being injected into by an AndroidInjector, into other objects?

查看:186
本文介绍了如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有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);
  }
}

此解决方案:


  1. 使样板设置代码与主代码脱钩

  2. 允许轻松注入测试实现

  3. 删除对Application类的依赖关系以设置依赖关系。

这篇关于如何将由AndroidInjector注入的android对象(服务,活动...)重新注入其他对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆