在项目上成功实现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();
}
的所有类中删除component
和component.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);
}
...
}
方法
inject()
类:
PersonsRemoteRepository
答案 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
和如何注入活动。并且有两个对应的组件ProjectApplicationComponent
和ApplicationComponent
通过组件依赖关系连接。
要注入到应用程序中,古斯塔沃(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
版本的字段,类型分别为RestClient
和PersonsRemoteRepository
。
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);