Android 官方示例:android-architecture 学习笔记(七)之todo-mvp-dagger
项目地址:https://github.com/googlesamples/android-architecture/tree/todo-mvp-dagger/项目结构Dagger2是完全静态的、编译时的依赖注入框架,用于Java和Android。本项目基于MVP和Dagger2。注:本文假设读者已基本了解Dagger2的使用源码分析Application DI@ComponentToD
项目地址:https://github.com/googlesamples/android-architecture/tree/todo-mvp-dagger/
项目结构
Dagger2是完全静态的、编译时的依赖注入框架,用于Java和Android。
本项目基于MVP和Dagger2。
注:本文假设读者已基本了解Dagger2的使用
源码分析
Application DI
@Component
ToDoApplication源码:
public class ToDoApplication extends Application {
private TasksRepositoryComponent mRepositoryComponent;
@Override
public void onCreate() {
super.onCreate();
mRepositoryComponent = DaggerTasksRepositoryComponent.builder()
.applicationModule(new ApplicationModule((getApplicationContext())))
.build();
}
public TasksRepositoryComponent getTasksRepositoryComponent() {
return mRepositoryComponent;
}
}
TasksRepositoryComponent作为Application中属性成员,onCreate()初始一次,那么它应该是一个全局变量。其源码:
@Singleton
@Component(modules = {TasksRepositoryModule.class, ApplicationModule.class})
public interface TasksRepositoryComponent {
TasksRepository getTasksRepository();
}
通过@Singleton注解可知,TasksRepositoryComponent在注入后,是一个单实例对象,同时又被应用于Appliation中,那么就是一个全局的单例对象。
提供一个获取TasksRepository对象的方法。
@Modules
通过@Component(modules = {TasksRepositoryModule.class, ApplicationModule.class})可知,提供依赖对象的两个类。
先来看下ApplicationModule源码:
@Module
public final class ApplicationModule {
private final Context mContext;
ApplicationModule(Context context) {
mContext = context;
}
@Provides
Context provideContext() {
return mContext;
}
}
只是通过 @Provides提供了一个Context对象。而其初始化,需要交由它处显示调用,后面会说。
再来看下TasksRepositoryModule源码:
@Module
public class TasksRepositoryModule {
@Singleton
@Provides
@Local
TasksDataSource provideTasksLocalDataSource(Context context) {
return new TasksLocalDataSource(context);
}
@Singleton
@Provides
@Remote
TasksDataSource provideTasksRemoteDataSource() {
return new FakeTasksRemoteDataSource();
}
}
TasksRepositoryModule提供了两个返回TasksDataSource单实例的方法。@Local、@Remote都使用了@Qualifier来定义,表示对实现相同接口的对象,作区分。
@Inject
注入了上面这两个对象后,而在Component中,要求注入的是TasksRepository对象,再来看下TasksRepository的相关源码:
@Inject
TasksRepository(@Remote TasksDataSource tasksRemoteDataSource,
@Local TasksDataSource tasksLocalDataSource) {
mTasksRemoteDataSource = tasksRemoteDataSource;
mTasksLocalDataSource = tasksLocalDataSource;
}
发现TasksRepository的构造,依赖于分别使用了@Remote和@Local的两个对象。
结合Dagger2生成的代码进行分析
回过头来看ToDoApplication#onCreate()中:
mRepositoryComponent = DaggerTasksRepositoryComponent.builder()
.applicationModule(new ApplicationModule((getApplicationContext())))
.build();
DaggerTasksRepositoryComponent就是Dagger2自动编译生成的一个类。其源码:
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerTasksRepositoryComponent implements TasksRepositoryComponent {
private Provider<TasksDataSource> provideTasksRemoteDataSourceProvider;
private Provider<Context> provideContextProvider;
private Provider<TasksDataSource> provideTasksLocalDataSourceProvider;
private Provider<TasksRepository> tasksRepositoryProvider;
private DaggerTasksRepositoryComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideTasksRemoteDataSourceProvider =
ScopedProvider.create(
TasksRepositoryModule_ProvideTasksRemoteDataSourceFactory.create(
builder.tasksRepositoryModule));
this.provideContextProvider =
ApplicationModule_ProvideContextFactory.create(builder.applicationModule);
this.provideTasksLocalDataSourceProvider =
ScopedProvider.create(
TasksRepositoryModule_ProvideTasksLocalDataSourceFactory.create(
builder.tasksRepositoryModule, provideContextProvider));
this.tasksRepositoryProvider =
ScopedProvider.create(
TasksRepository_Factory.create(
provideTasksRemoteDataSourceProvider, provideTasksLocalDataSourceProvider));
}
@Override
public TasksRepository getTasksRepository() {
return tasksRepositoryProvider.get();
}
public static final class Builder {
private TasksRepositoryModule tasksRepositoryModule;
private ApplicationModule applicationModule;
private Builder() {}
public TasksRepositoryComponent build() {
if (tasksRepositoryModule == null) {
this.tasksRepositoryModule = new TasksRepositoryModule();
}
if (applicationModule == null) {
throw new IllegalStateException(
ApplicationModule.class.getCanonicalName() + " must be set");
}
return new DaggerTasksRepositoryComponent(this);
}
public Builder tasksRepositoryModule(TasksRepositoryModule tasksRepositoryModule) {
this.tasksRepositoryModule = Preconditions.checkNotNull(tasksRepositoryModule);
return this;
}
public Builder applicationModule(ApplicationModule applicationModule) {
this.applicationModule = Preconditions.checkNotNull(applicationModule);
return this;
}
}
}
内部使用了Builder模式。有一个内部类Builder。Builder中有TasksRepositoryModule和ApplicationModule的注入方法。build()返回TasksRepositoryComponent。TasksRepositoryComponent的初始化,会调用initialize(builder),内部主要是解析对@Provides,注入各对象需要的Provider。Provider中就一个方法:T get()。如这里的获取TasksRepository:
public TasksRepository getTasksRepository() {
return tasksRepositoryProvider.get();
}
Activity DI
再简单分析下 Activity中的依赖注入。
每个业务功能模块包下都有一个Component,一个Module
tasks模块
TasksActivity主要代码:
public class TasksActivity extends AppCompatActivity {
@Inject
TasksPresenter mTasksPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tasks_act);
TasksFragment tasksFragment =
(TasksFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);
if (tasksFragment == null) {
// Create the fragment
tasksFragment = TasksFragment.newInstance();
ActivityUtils.addFragmentToActivity(
getSupportFragmentManager(), tasksFragment, R.id.contentFrame);
}
// Create the presenter
DaggerTasksComponent.builder()
.tasksRepositoryComponent(((ToDoApplication) getApplication()).getTasksRepositoryComponent())
.tasksPresenterModule(new TasksPresenterModule(tasksFragment)).build()
.inject(this);
// Load previously saved state, if available.
if (savedInstanceState != null) {
TasksFilterType currentFiltering =
(TasksFilterType) savedInstanceState.getSerializable(CURRENT_FILTERING_KEY);
mTasksPresenter.setFiltering(currentFiltering);
}
}
}
DaggerTasksComponent由TasksComponent生成。指定TasksPresenterModule。
这里重要说下inject()的实现,跟踪进去,发现DaggerTasksComponent#inject():
public void inject(TasksActivity activity) {
tasksActivityMembersInjector.injectMembers(activity);
}
浏览代码,发现有两个MembersInjector:tasksPresenterMembersInjector和tasksActivityMembersInjector。
tasksActivityMembersInjector的生成,因在TasksActivity中,使用了@Inject;
tasksPresenterMembersInjector的生成,因在TasksPresenter中有
@Inject
void setupListeners() {
mTasksView.setPresenter(this);
}
基本就分析到这了。
Component中指定注入方,在注入方创建DaggerComponent,并调用注入方法,以注入使用了@Inject的对象和方法
更多推荐


所有评论(0)