Android在每个我需要的自动注入匕首模块

时间:2019-04-14 09:50:11

标签: android dependency-injection dagger-2

在项目上成功实现Dagger之后,我必须为要使用的每个类指定dagger并注入模块,例如RestClient的{​​{1}},我想知道有什么方法可以自动定义retrofit进入课堂?

例如,我的实现是:

components

和我的public class CoreApplication extends MultiDexApplication { private static ProjectApplicationComponent component; private RestClient restClient; private Picasso picasso; private Handler handler; @Override public void onCreate() { super.onCreate(); ... component = DaggerProjectApplicationComponent.builder() .contextModule(new ContextModule(this)) .networkServiceModule(new NetworkServiceModule(ClientSettings.SERVER_URL)) .build(); restClient= component.apiService(); picasso = component.getPicasso(); handler = component.getHandler(); } public static ProjectApplicationComponent getComponent() { return component; } } ,我定义了我想注入模块的女巫类或活动或片段:

ApplicationComponent
我想注入@ActivitiesScope @Component(dependencies = ProjectApplicationComponent.class) public interface ApplicationComponent { void inject(PersonsRemoteRepository personsRemoteRepository); } 以使用翻新的

PersonsRemoteRepository

RestClient

我的public class PersonsRemoteRepository implements PersonsRepository { @Inject private RestClient restClient; private final ApplicationComponent component; public PersonsRemoteRepository() { component = DaggerApplicationComponent.builder() .projectApplicationComponent(CoreApplication.getComponent()) .build(); component.inject(this); } ... } 类是:

RestClient

我的意思是从我要注入的public interface RestClient { @Headers("Content-Type: application/json") @POST("/api/v1/getPersons") Observable<List<Person>> getPersons(); } 的所有类中删除componentcomponent.inject(this);

RestClient

例如简化的@Inject private RestClient restClient; 类应为:

PersonsRemoteRepository

预先感谢


更新帖子

在此行代码中,我的活动public class PersonsRemoteRepository implements PersonsRepository { @Inject private RestClient restClient; public PersonsRemoteRepository() { } ... } 无效:

inject(this)

我的活动

CoreApplication.getComponent().inject(this);

在此屏幕快照中,您看到我没有public class LoginActivity extends AppCompatActivity{ @Inject PersonsRemoteRepository personsRemoteRepository; @Inject RestClient restClient; private LoginActivityBinding mBinding; private LoginMethodsToPageViewModel viewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CoreApplication.getComponent().inject(this); mBinding = DataBindingUtil.setContentView(this, R.layout.login_activity); personsRemoteRepository = new PersonsRemoteRepository(restClient); viewModel = new LoginMethodsToPageViewModel(personsRemoteRepository, this, mBinding); mBinding.setViewModel(viewModel); } ... } 方法

enter image description here

更改后的

inject()类:

PersonsRemoteRepository

2 个答案:

答案 0 :(得分:1)

您不需要为每个要注入依赖项的类构建组件。可以通过带有@Inject注释的构造函数来提供依赖关系:

public class PersonsRemoteRepository implements PersonsRepository {

    private RestClient restClient;

    @Inject
    public PersonsRemoteRepository(RestClient restClient) {
         this.restClient = restClient;
    }
}

其他需要该存储库的其他类也可以这样做:

public class AnyOtherClass {
    private PersonsRemoteRepository personsRemoteRepository;

    @Inject
    public AnyOtherClass(PersonsRemoteRepository personsRemoteRepository) {
        this.personsRemoteRepository = personsRemoteRepository;
    }

对于由Android创建的实例的类,只需使用component.inject,例如Application,Activities和Fragments。

public class MyActivity {
    @Inject PersonsRemoteRepository personsRemoteRepository;

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

        CoreApplication.getComponent().inject(this);
    }
}

CoreApplication中需要进行的更改:

public class CoreApplication extends MultiDexApplication {
    private static ProjectApplicationComponent component;

    @Inject private RestClient restClient;
    @Inject private Picasso picasso;
    @Inject private Handler handler;

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

        ...
        component = DaggerProjectApplicationComponent.builder()
                .contextModule(new ContextModule(this))
                .networkServiceModule(new NetworkServiceModule(ClientSettings.SERVER_URL))
                .build();

        component.inject(this);
    }
}

您的ApplicationComponent中需要进行的更改:

@ActivitiesScope
@Component(dependencies = ProjectApplicationComponent.class)
public interface ApplicationComponent {
    void inject(CoreApplication coreApplication);

    void inject(MyActivity myActivity);
}

答案 1 :(得分:1)

有两个问题,如何注入CoreApplication和如何注入活动。并且有两个对应的组件ProjectApplicationComponentApplicationComponent通过组件依赖关系连接。


要注入到应用程序中,古斯塔沃(Gustavo)的答案很有用:

  • CoreApplication的字段注释为@Inject
  • 用成员注入方法替换ProjectApplicationComponent中的供应方法:

    @ApplicationScope
    @Component(
            modules = {
                ContextModule.class,
                NetworkServiceModule.class,
                ...,
            })
    public interface ProjectApplicationComponent {
        // Members-injection method
        void inject(CoreApplication coreApplication);
    }
    
  • 构造一个ProjectApplicationComponent并调用inject方法:

    // CoreApplication.onCreate
    component =
        DaggerProjectApplicationComponent.builder()
            .contextModule(new ContextModule(this))
            .networkServiceModule(...)
            .build();
    component.inject(/* coreApplication= */ this);
    

要注入LoginActivity,依赖的ApplicationComponent应该具有成员注入方法:

@ActivitiesScope
@Component(dependencies = ProjectApplicationComponent.class)
public interface ApplicationComponent {
    void inject(LoginActivity loginActivity);
}

回想一下,您的LoginActivity具有两个@Inject版本的字段,类型分别为RestClientPersonsRemoteRepository

public class LoginActivity extends AppCompatActivity {
    @Inject PersonsRemoteRepository personsRemoteRepository;
    @Inject RestClient restClient;
}

为了使依赖的ApplicationComponent获得RestClient,被依赖的ProjectApplicationComponent应该公开一种提供方法:

@ApplicationScope
@Component(modules = {...})
public interface ProjectApplicationComponent {
    // Members-injection method
    void inject(CoreApplication coreApplication);

    // Provision method
    RestClient getRestClient();
}

对于PersonsRemoteRepository,Dagger可以使用构造函数注入来构造一个:

// May be scoped @ActivitiesScope, or not
public class PersonsRemoteRepository implements PersonsRepository {
    private final RestClient restClient;

    @Inject
    PersonsRemoteRepository(RestClient restClient) {
        this.restClient = restClient;
    }
}

然后,当您创建LoginActivity时,请按以下步骤构建Dagger生成的组件:

// LoginActivity.onCreate
ApplicationComponent component =
    DaggerApplicationComponent.builder()
        .projectApplicationComponent(CoreApplication.getComponent())
        .build();
component.inject(/* loginActivity= */ this);