Как использовать Dagger2 в Android, чтобы проще вводить объекты активности? - PullRequest
0 голосов
/ 24 августа 2018

На Android, при использовании Dagger2, я должен вызывать следующую строку для каждого вида деятельности, который использует apiService:

@Inject
public ApiService apiService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    DaggerApiComponent.builder()
                      .activityModule(new ActivityModule(this))
                      .build()
                      .inject(this);

    //...
}

Как я могу обобщить его примерно так:

DaggerApiComponent.builder()
                  .activity(this)
                  .build()
                  .inject(this);

или даже проще, например:

MyApplication.injectApiService(this);

Как мне поменять компоненты и модули, чтобы использовать Dagger2 с меньшим количеством кода для вставки копий в моих действиях?

Вот мой ApiComponent:

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {

    void inject(MainActivity activity);
    void inject(...
}

Вот ApiModule:

@Module(includes = {RetrofitModule.class, ActivityModule.class})
public class ApiModule {

    @Singleton
    @Provides
    public static ApiService provideApiService(Activity activity) {
        //...
    }
}

и ActivityModule:

@Module
public class ActivityModule {

    private final Activity context;

    public ActivityModule(Activity context) {
        this.context = context;
    }

    @Singleton
    @Provides
    public Activity provideActivityContext() {
        return context;
    }
}

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Подход такого «DI» имеет две проблемы:

  • , как то, что сказал ОП: нам нужно копировать и вставлять этот шаблон в любое место, где нам требуется инъекция, что утомительно и трудно реорганизовать.
  • Инъекционер (например, Activity) не должен знать, откуда взялся экземпляр @Inject, и его интересует только "эй, дай мне его экземпляр".

Чтобы решить вышеуказанные проблемы, dagger.android приходит на помощь.

  1. Создать AndroidInjector для каждого компонента.
// App component
@Singleton
@Component(
    modules = [
        AndroidSupportInjectionModule::class, // build-in module
        ActivityBindingModule::class,            
        AppModule::class
    ]
)
interface AppComponent : AndroidInjector<MainApplication> {
    // we need to bind `MainApplication` instance to this component,
    // so we have a builder here.
    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<MainApplication>()
}
// Each controller (e.g. `Activity` / `Fragment` / `Service`) subcomponents
@Module
abstract class ActivityBindingModule {
    // will generate a FooActivitySubcomponent under ActivityBindingModule's component
    @ActivityScoped
    @ContributesAndroidInjector(modules = [FooModule::class])
    internal abstract fun fooActivity(): FooActivity

    @ActivityScoped
    @ContributesAndroidInjector(modules = [BarModule::class])
    internal abstract fun barActivity(): BarActivity
}
Подключите ваши AndroidInjector s, чтобы он мог сделать для нас инъекцию, используя предоставленный инжектор на шаге 1.
// App component
class MainApplication : DaggerApplication() {

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().create(this)
    }
}
// Each controller subcomponents
class FooActivity : DaggerAppCompatActivity() {
    @Inject lateinit var foo: Foo

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState) 
        // no need to call inject() here anymore!
        foo.doSth()
    }
}

Для конкретного примера: проверьте iosched

0 голосов
/ 24 августа 2018

Вы можете использовать Android Activity инжектор, использование хорошо описано здесь .

...