Внедрение зависимостей в запланированном JobService с помощью Dagger 2 - PullRequest
0 голосов
/ 17 сентября 2018

Какой лучший способ внедрить зависимости в запланированную службу заданий в Android. Мой JobService должен работать ночью, чтобы что-то делать.

В конструкторе JobService я пытаюсь внедрить свои зависимости в мой класс приложения.

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();
    }
  }
}

1 Ответ

0 голосов
/ 17 сентября 2018

Вы должны использовать AndroidInjector для внедрения классов Android, таких как «Деятельности / Фрагменты / Услуги / BroadcastReceivers / ContentProviders».

Сначала убедитесь, что вы добавили зависимость «dagger-android» от вашей build.gradle

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();
    }
}

ActivityBuilderModule и ServiceBuilderModule и ссылается на все ваши компоненты деятельности и обслуживания, используя удобную аннотацию 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 фрагментов вы получите FragmentBuilderModule из вашего MainActivityModule

@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() ;

    //...
}

Вы можете увидеть больше из моего шаблона проекта здесь хотя это kotlin.

...