首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重新注入android对象,(Service,Activity...)被AndroidInjector注入,注入到其他对象?

如何重新注入android对象,(Service,Activity...)被AndroidInjector注入,注入到其他对象?
EN

Stack Overflow用户
提问于 2019-06-25 23:16:28
回答 1查看 276关注 0票数 0

问题是我还有一个ServiceManager类,它需要一个对服务的引用来“管理”服务任务。即

应用程序

代码语言:javascript
复制
  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;
    }

}

组件

代码语言:javascript
复制
@Singleton
@Component(modules = {  /* modules */})
public interface ServiceComponent extends AndroidInjector<ApplicationBase > {

    ServiceManager provideServiceManager();
    void inject(ApplicationBase appBase);
    // ..
}

模块

代码语言:javascript
复制
@Module
public abstract class MediaPlaybackServiceModule {

    @ContributesAndroidInjector
    abstract MediaPlaybackService provideMediaPlaybackService();

}

MediaPlaybackService MyService

代码语言:javascript
复制
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类中设置“服务”引用。

服务管理器类如下所示:

代码语言:javascript
复制
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;
    }
}

但理想情况下,我希望服务管理器构造函数看起来像这样。

代码语言:javascript
复制
@Inject
public ServiceManager(MediaPlaybackService mediaPlaybackService, MediaSessionAdapter mediaSession,
                      MyNotificationManager myNotificationManager) {
    this.service = mediaPlaybackService;
    this.mediaSession = mediaSession;
    this.notificationManager = myNotificationManager;
}

我需要对我的dagger2代码进行哪些更改才能实现这一点?

注意:为了简单起见,我删除了应用程序中使用的额外代码,但可以在here中找到它

EN

回答 1

Stack Overflow用户

发布于 2019-07-02 22:40:24

因此,对于那些面临与我类似问题的人,我已经用dagger-android做了很多实验,并发现做以下事情要简单得多:

1)使活动抽象化

代码语言:javascript
复制
public abstract MainActivity extends AppCompatActivity {
  ...
  abstract void initDependencies();
  ...

  @Inject
  public void setMyDependency(MyDependency myDependency) { ... }
}

2)创建一个子类来初始化您的依赖项,从而删除活动中的dagger依赖项

代码语言:javascript
复制
public MainActivityProduction extends MainActivity  {
  @Override
  void initDependencies() {
     DaggerMainActivityComponent.factory().create(..., this)
     .inject(this);
  }
  @Override
  public void onCreate() {
    initDependencies();
    super.onCreate();
  }
}

注意:这允许使用单独的组件进行测试,如dagger documentation https://dagger.dev/testing中所建议的。

代码语言:javascript
复制
public MainActivityTesting extends MainActivity  {
  @Override
  void initDependencies() {
     DaggerMainActivityTestingComponent.factory().create(..., this)
     .inject(this);
  }
  @Override
  public void onCreate() {
    initDependencies();
    super.onCreate();
  }
}

3)因此,您的组件将如下所示:

代码语言:javascript
复制
@Component(modules = { /* modules */})
public interface MainActivityComponent {
  ...
  @Component.Factory
  interface Factory {
    MainActivityComponent create(...,
                    @BindsInstance MainActivity);
  }
}

这意味着您可以让任何模块引用您的MainActivity

代码语言:javascript
复制
@Module
public class MyDependencyModule {

  @Provides
  public MyDependency providesMyDependency(MainActivity MainActivity) {
     return new MyDependency(mainActivity);
  }
}

此解决方案:

  1. 将样板设置代码与主代码解耦
  2. 允许测试实现轻松地依赖于用于设置应用程序的应用程序类
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56757242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档