如何使用Dagger 2.11 Android注入器在协作者中注入当前活动 [英] How to inject current activity in a collaborator using Dagger 2.11 Android injector

查看:79
本文介绍了如何使用Dagger 2.11 Android注入器在协作者中注入当前活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经将当前活动或活动上下文注入由注入父活动(BaseActivity或AppCompactActivity)的多个活动共享的一些协作者。
但由于某些原因,我无法使用Dagger 2.11 Android Injector做到这一点。



这是我的活动模块:

  @Module 
公共类ActivityModule {

私人最终Activity活动;
public ActivityModule(Activity activity){
this.activity = activity;
}

@Provides
@ PerActivity
ActColaborator ProvideActCollaborator(){
返回新的ActColaborator();
}

@Provides
@PerActivity
Activity ProvideActivity(){
return activity;
}
}

我尝试注入这些类:

  @Inject 
public Navigator(ActColaborator actColaborator,
BaseActivity活动){
this.actColaborator = actColaborator;
this.activity =活动;
}

但是我得到了



没有$ Inject构造函数或@Provides注释方法,就无法提供

  BaseActivity。 

如果我删除了BaseActivity内容,则 ActColaborator 正确注入。
问题在于,ActivityModule不再在Activity中实例化,而将过去的活动本身传递给了它:

  //旧的Android注入器代码
this.activityComponent = getApplicationComponent()
.getActivityComponentBuilder()
.activityModule(new ActivityModule(this)
.build() ;

所以我不知道如何使当前活动可用于注入其合作者。 p>

根据要求提供更多信息:
我为这三个活动提供了三个不同的组件类,但它们都像这样:

  @PerActivity 
@Subcomponent
公共接口MainActivityComponent扩展了AndroidInjector< MainActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< MainActivity> {
}
}

和ActivityBindingModule:

  @Module(子组件= {
MainActivityComponent.class,
DetailActivityComponent.class,
AnotherActivityComponent.class
})
抽象公共类ActivityBindingModule {
@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory< ;?扩展Activity> mainActivityInjectorFactory(
MainActivityComponent.Builder builder);
.....


解决方案

好,终于找到了问题所在。
使用具有依赖项或子组件的组件,我可以在 BaseActivity 级别创建 ActivityComponent 使用它将属性注入顶级活动。



这样,当我将 Activity 注入协作者时,当前的 ActivityComponent



Android Injector的问题是我们不再从代码中实例化 ActivityComponent 了,它是 AndroidInjector 发挥作用的人,因此我们需要在自己的模块中提供每个Activity。



例如Main :

  @Module 
公共抽象类MainActivityModule {
@Provides
@PerActivity
静态活动offerActivity(MainActivity活动){
返回活动;
}
}

详细信息:

  @Module 
公共抽象类DetailActivityModule {
@Provides
@PerActivity
静态活动provideActivity(DetailActivity活动){
退货活动;
}
}

常见规定:

  @Module 
公共抽象类ActivityModule {
@Provides
@PerActivity
静态ActColaborator offerActCollaborator(){
返回新的ActColaborator();
}
}

然后我们在Main中声明它们:

  @PerActivity 
@Subcomponent(modules = {ActivityModule.class,MainActivityModule.class})
公共接口MainActivityComponent扩展了AndroidInjector< ; MainActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< MainActivity> {
}
}

详细信息:

  @PerActivity 
@Subcomponent(modules = {ActivityModule.class,DetailActivityModule.class})
公共接口DetailActivityComponent扩展了AndroidInjector< DetailActivity> {
@ Subcomponent.Builder
抽象类Builder扩展了AndroidInjector.Builder< DetailActivity> {
}
}

最后,我们可以将当前活动注入我们共享的协作者:

 私人最终活动活动; 

@Inject
public Navigator(活动活动){
this.activity = activity;
}


I used to inject the current activity or activity context on some collaborators shared by several activities injecting the parent activity (BaseActivity or AppCompactActivity). But for some reason I cannot do it using Dagger 2.11 Android Injector.

This is my Activity Module:

@Module
public class ActivityModule {

    private final Activity activity;
    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    @Provides
    @PerActivity
    ActColaborator provideActCollaborator() {
        return new ActColaborator();
    }

    @Provides
    @PerActivity
    Activity provideActivity() {
        return activity;
    }
}

I try to inject those classes:

    @Inject
    public Navigator(ActColaborator actColaborator, 
                     BaseActivity activity) {
        this.actColaborator = actColaborator;
        this.activity = activity;
    }

But I get a

BaseActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method.

If I remove the BaseActivity stuff, ActColaborator is correctly injected. The problem is that ActivityModule is not longer instantiated in the Activity passing it the Activity itself as it used to be:

    //old, pre Android-injector code
    this.activityComponent = getApplicationComponent()
            .getActivityComponentBuilder()
            .activityModule(new ActivityModule(this))
            .build();

So I have no idea of how to make the current activity available for injection into its collaborators.

More info as requested: I have three different component classes for the three activities, but all of them like this:

@PerActivity
@Subcomponent
public interface MainActivityComponent extends     AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }
}

And the ActivityBindingModule:

@Module(subcomponents = {
        MainActivityComponent.class,
        DetailActivityComponent.class,
        AnotherActivityComponent.class
})
abstract public class ActivityBindingModule {
    @Binds
    @IntoMap
    @ActivityKey(MainActivity.class)
    abstract AndroidInjector.Factory<? extends Activity> mainActivityInjectorFactory(
            MainActivityComponent.Builder builder);
.....

解决方案

Ok, finally found what the problem was. Using components with dependency or subcomponents I'm able to create the ActivityComponent at the BaseActivity level and then use it to inject properties into the top level activities.

Thas way, when I injected Activity into collaborators the current ActivityComponent that held the current Activity was used. Easy.

The problem with Android Injector is that we don't instantiate the ActivityComponent from the code anymore, it is AndroidInjector who does the magic, so we need to provide each Activity in its own module.

For example Main:

@Module
public abstract class MainActivityModule {
    @Provides
    @PerActivity
    static Activity provideActivity(MainActivity activity) {
        return activity;
    }
}

Detail:

@Module
public abstract class DetailActivityModule {
    @Provides
    @PerActivity
    static Activity provideActivity(DetailActivity activity) {
        return activity;
    }
}

Common provides:

@Module
public abstract class ActivityModule {
    @Provides
    @PerActivity
    static ActColaborator provideActCollaborator() {
        return new ActColaborator();
    }
}

Then we declare them in Main:

@PerActivity
@Subcomponent(modules = { ActivityModule.class, MainActivityModule.class})
public interface MainActivityComponent extends AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<MainActivity> {
    }
}

And detail:

@PerActivity
@Subcomponent(modules = { ActivityModule.class, DetailActivityModule.class})
public interface DetailActivityComponent extends AndroidInjector<DetailActivity> {
    @Subcomponent.Builder
    abstract class Builder extends AndroidInjector.Builder<DetailActivity> {
    }
}

And finally, we can inject the current activity in our shared collaborator:

private final Activity activity;

@Inject
public Navigator(Activity activity) {
    this.activity = activity;
}

这篇关于如何使用Dagger 2.11 Android注入器在协作者中注入当前活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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