【问题标题】:Dependency injection in a scheduled JobService with Dagger 2使用 Dagger 2 在计划的 JobService 中进行依赖注入
【发布时间】:2018-09-17 12:44:45
【问题描述】:

在 Android 的计划作业服务中注入依赖项的最佳方式是什么。 我的 JobService 计划在晚上运行以做一些事情。

在 JobService 构造函数中,我试图将我的依赖项注入到我的 Application 类中。

MyApp.component().inject(this);

但有时MyApp此时未初始化,因此注入失败。

也许我以错误的方式使用 Dagger?还是我必须为 JobService 创建一个自己的组件?

这是我的应用程序类

public class MyApp extends Application {
  private static AppComponent appComponent;

  @Override
  public void onCreate() {
    super.onCreate();

    buildAppComponent();

  }

  public static AppComponent component(){
    return appComponent;
  }

  private void buildAppComponent(){
    if(appComponent == null){
        appComponent = DaggerAppComponent.builder()
            .appModule(new AppModule(this))
            .build();
    }
  }
}

【问题讨论】:

    标签: android dependency-injection dagger jobservice


    【解决方案1】:

    您应该使用 AndroidInjector 来注入 android 类,例如 Activities/Fragments/Services/BroadcastReceivers/ContentProviders。

    首先确保您从 build.gradle 添加了 dagger-android 依赖项

    implementation 'com.google.dagger:dagger:2.16'
    implementation 'com.google.dagger:dagger-android:2.16'
    implementation 'com.google.dagger:dagger-android-support:2.16'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.16'
    

    然后确保你的应用组件继承自AndroidInjector

    @Singleton
    @Component(modules = {AndroidSupportInjectionModule.class,
                          ApplicationModule.class,
                          ActivityBuilderModule::class,
                          ServiceBuilderModule::class})
    public interface ApplicationComponent extends AndroidInjector<MyApp> {
        @Component.Builder
        interface Builder {
            @BindsInstance
            Builder application(MyApp application);
    
            ApplicationComponent build();
        }
    }
    

    ActivityBuilderModuleServiceBuilderModule 使用方便的注释 ContributesAndroidInjector 引用您所有的活动和服务子组件,该注释将自动为您生成子组件

    @Module
    abstract class ActivityBuilderModule {
        @ContributesAndroidInjector(modules = {MainActivityModule.class})
        @ActivityScope
        abstract MainActivity contributeMainActivity();
    
        @ContributesAndroidInjector(modules = {DummyModule.class})
        @ActivityScope
        abstract DummyActivity contributeDummyActivity();
    
        //...
    }
    

    服务也一样

    @Module
    abstract class ServiceBuilderModule {
        @ContributesAndroidInjector
        abstract MyService contributeAuthenticatorService();
    
        //...
    }
    

    最后,您的MyApp 应该是什么样子的

    public class MyApp extends DaggerApplication() {
        private ApplicationComponent appComponent;
    
        @Override
        public void onCreate() {
            super.onCreate();
            appComponent = DaggerApplicationComponent.builder()
                                                      .application(this)
                                                      .build();
        }
    
        AndroidInjector<? extends DaggerApplication> applicationInjector(){
            return appComponent;
        }
    }
    

    您的服务现在应该是可注入的,为了结束它,您当然也需要注入片段,例如对于MainActivity 片段,您将从您的MainActivityModule 中创建一个FragmentBuilderModule

    @Module(includes = {FragmentBuilderModule.class})
    abstract class MainActivityModule {
        @Binds
        @ActivityScope
        abstract AppCompatActivity bindActivity(MainActivity activity);
    
        //...
    }
    

    这里是FragmentBuilderModule

    @Module
    abstract class FragmentBuilderModule {
        @ContributesAndroidInjector(modules = {HomeFragmentModule.class})
        @FragmentScope
        abstract HomeFragment contributeHomeFragment();
    
        @ContributesAndroidInjector(modules = DummyFragmentModule.class})
        @FragmentScope
        abstract DummyFragment contributeDummyFragment() ;
    
        //...
    }
    

    您可以从我的项目模板here 中看到更多信息,尽管它是 kotlin。

    【讨论】:

    • 非常感谢,这听起来很有趣,但是有没有办法不切换到AndroidInjector?
    • 你可以从你的 Service onCreate 方法中添加 MyApp.component().inject(this) 并在你的 void inject(MyService service) 中添加一个 void inject(MyService service) 行,但是 Android 注入器是正确的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多